blob: 53796b81874679dd3019b6cc030e529528528478 [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
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000377class FakeReceiveStatistics : public NullReceiveStatistics {
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,
382 uint8_t fraction_lost)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000383 : lossy_stats_(new LossyStatistician(last_sequence_number,
384 cumulative_lost,
385 fraction_lost)) {
386 stats_map_[send_ssrc] = lossy_stats_.get();
387 }
388
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000389 StatisticianMap GetActiveStatisticians() const override { return stats_map_; }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000390
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000391 StreamStatistician* GetStatistician(uint32_t ssrc) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000392 return lossy_stats_.get();
393 }
394
395 private:
396 class LossyStatistician : public StreamStatistician {
397 public:
398 LossyStatistician(uint32_t extended_max_sequence_number,
399 uint32_t cumulative_lost,
400 uint8_t fraction_lost) {
401 stats_.fraction_lost = fraction_lost;
402 stats_.cumulative_lost = cumulative_lost;
403 stats_.extended_max_sequence_number = extended_max_sequence_number;
404 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000405 bool GetStatistics(RtcpStatistics* statistics, bool reset) override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000406 *statistics = stats_;
407 return true;
408 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000409 void GetDataCounters(size_t* bytes_received,
410 uint32_t* packets_received) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000411 *bytes_received = 0;
412 *packets_received = 0;
413 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000414 void GetReceiveStreamDataCounters(
415 StreamDataCounters* data_counters) const override {}
416 uint32_t BitrateReceived() const override { return 0; }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000417 bool IsRetransmitOfOldPacket(const RTPHeader& header,
418 int64_t min_rtt) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000419 return false;
420 }
421
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000422 bool IsPacketInOrder(uint16_t sequence_number) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000423 return true;
424 }
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000425
426 RtcpStatistics stats_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000427 };
428
kwiberg27f982b2016-03-01 11:52:33 -0800429 std::unique_ptr<LossyStatistician> lossy_stats_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000430 StatisticianMap stats_map_;
431};
432
brandtre602f0a2016-10-31 03:40:49 -0700433class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100434 public:
brandtre602f0a2016-10-31 03:40:49 -0700435 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800436 bool use_nack,
437 bool expect_red,
438 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800439 const std::string& codec,
440 VideoEncoder* encoder)
brandtr20d45472017-01-02 00:34:27 -0800441 : EndToEndTest(kTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800442 encoder_(encoder),
Peter Boström39593972016-02-15 11:27:15 +0100443 payload_name_(codec),
444 use_nack_(use_nack),
445 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700446 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800447 sent_media_(false),
448 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800449 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100450
brandtr20d45472017-01-02 00:34:27 -0800451 // Some of the test cases are expected to time out and thus we are using
452 // a shorter timeout window than the default here.
453 static constexpr size_t kTimeoutMs = 10000;
454
Stefan Holmer4654d202015-12-08 09:10:43 +0100455 private:
456 Action OnSendRtp(const uint8_t* packet, size_t length) override {
457 RTPHeader header;
458 EXPECT_TRUE(parser_->Parse(packet, length, &header));
459
Stefan Holmer4654d202015-12-08 09:10:43 +0100460 int encapsulated_payload_type = -1;
461 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100462 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100463 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
464 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100465 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100466 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
467 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100468 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100469 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100470 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
471 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100472 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
473 length) {
474 // Not padding-only, media received outside of RED.
475 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800476 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100477 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100478 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000479
Stefan Holmer4654d202015-12-08 09:10:43 +0100480 if (header_extensions_enabled_) {
481 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
482 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
483 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
484 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
485 // 24 bits wrap.
486 EXPECT_GT(prev_header_.extension.absoluteSendTime,
487 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000488 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100489 EXPECT_GE(header.extension.absoluteSendTime,
490 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200491 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100492 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
493 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
494 prev_header_.extension.transportSequenceNumber;
495 EXPECT_EQ(1, seq_num_diff);
496 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200497
Stefan Holmer4654d202015-12-08 09:10:43 +0100498 if (encapsulated_payload_type != -1) {
499 if (encapsulated_payload_type ==
500 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700501 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800502 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100503 } else {
brandtr65a1e772016-12-12 01:54:58 -0800504 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000505 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000506 }
507
brandtr20d45472017-01-02 00:34:27 -0800508 if (sent_media_ && sent_ulpfec_) {
509 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100510 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000511
Stefan Holmer4654d202015-12-08 09:10:43 +0100512 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000513
Stefan Holmer4654d202015-12-08 09:10:43 +0100514 return SEND_PACKET;
515 }
516
Peter Boström39593972016-02-15 11:27:15 +0100517 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
518 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
519 // Configure some network delay.
520 const int kNetworkDelayMs = 100;
521 FakeNetworkPipe::Config config;
brandtr65a1e772016-12-12 01:54:58 -0800522 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100523 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700524 return new test::PacketTransport(
525 sender_call, this, test::PacketTransport::kSender,
526 VideoSendStreamTest::payload_type_map_, config);
Peter Boström39593972016-02-15 11:27:15 +0100527 }
528
stefanff483612015-12-21 03:14:00 -0800529 void ModifyVideoConfigs(
530 VideoSendStream::Config* send_config,
531 std::vector<VideoReceiveStream::Config>* receive_configs,
532 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100533 if (use_nack_) {
534 send_config->rtp.nack.rtp_history_ms =
535 (*receive_configs)[0].rtp.nack.rtp_history_ms =
536 VideoSendStreamTest::kNackRtpHistoryMs;
537 }
brandtr696c9c62016-12-19 05:47:28 -0800538 send_config->encoder_settings.encoder = encoder_;
Peter Boström39593972016-02-15 11:27:15 +0100539 send_config->encoder_settings.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700540 send_config->rtp.ulpfec.red_payload_type =
541 VideoSendStreamTest::kRedPayloadType;
542 send_config->rtp.ulpfec.ulpfec_payload_type =
543 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800544 EXPECT_FALSE(send_config->rtp.extensions.empty());
545 if (!header_extensions_enabled_) {
546 send_config->rtp.extensions.clear();
547 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100548 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700549 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100550 }
brandtrb5f2c3f2016-10-04 23:28:39 -0700551 (*receive_configs)[0].rtp.ulpfec.red_payload_type =
552 send_config->rtp.ulpfec.red_payload_type;
553 (*receive_configs)[0].rtp.ulpfec.ulpfec_payload_type =
554 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100555 }
556
557 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800558 EXPECT_EQ(expect_ulpfec_, Wait())
559 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100560 }
561
brandtr696c9c62016-12-19 05:47:28 -0800562 VideoEncoder* const encoder_;
563 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100564 const bool use_nack_;
565 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700566 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800567 bool sent_media_;
568 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100569 bool header_extensions_enabled_;
570 RTPHeader prev_header_;
571};
572
brandtre602f0a2016-10-31 03:40:49 -0700573TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800574 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
575 UlpfecObserver test(true, false, true, true, "VP8", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800576 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100577}
578
brandtre602f0a2016-10-31 03:40:49 -0700579TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800580 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
581 UlpfecObserver test(false, false, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100582 RunBaseTest(&test);
583}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000584
Peter Boström39593972016-02-15 11:27:15 +0100585// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
586// since we'll still have to re-request FEC packets, effectively wasting
587// bandwidth since the receiver has to wait for FEC retransmissions to determine
588// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700589TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800590 std::unique_ptr<VideoEncoder> encoder(
591 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
592 UlpfecObserver test(false, true, true, false, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100593 RunBaseTest(&test);
594}
595
596// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800597TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800598 std::unique_ptr<VideoEncoder> encoder(
599 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
600 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100601 RunBaseTest(&test);
602}
603
danilchap9f5b6222017-03-02 06:22:21 -0800604// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
605TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800606 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
607 UlpfecObserver test(false, true, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100608 RunBaseTest(&test);
609}
610
Peter Boström12996152016-05-14 02:03:18 +0200611#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800612// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
613TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800614 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
615 UlpfecObserver test(false, true, true, true, "VP9", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800616 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000617}
Peter Boström12996152016-05-14 02:03:18 +0200618#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000619
brandtre78d2662017-01-16 05:57:16 -0800620TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800621 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800622 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800623 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
624 RunBaseTest(&test);
625}
626
brandtr39f97292016-11-16 22:57:50 -0800627// TODO(brandtr): Move these FlexFEC tests when we have created
628// FlexfecSendStream.
629class FlexfecObserver : public test::EndToEndTest {
630 public:
631 FlexfecObserver(bool header_extensions_enabled,
632 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800633 const std::string& codec,
634 VideoEncoder* encoder)
brandtr39f97292016-11-16 22:57:50 -0800635 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800636 encoder_(encoder),
brandtr39f97292016-11-16 22:57:50 -0800637 payload_name_(codec),
638 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800639 sent_media_(false),
640 sent_flexfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800641 header_extensions_enabled_(header_extensions_enabled) {}
brandtr39f97292016-11-16 22:57:50 -0800642
643 size_t GetNumFlexfecStreams() const override { return 1; }
644
645 private:
646 Action OnSendRtp(const uint8_t* packet, size_t length) override {
647 RTPHeader header;
648 EXPECT_TRUE(parser_->Parse(packet, length, &header));
649
brandtr39f97292016-11-16 22:57:50 -0800650 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
651 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
652 sent_flexfec_ = true;
653 } else {
654 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
655 header.payloadType);
656 EXPECT_EQ(VideoSendStreamTest::kVideoSendSsrcs[0], header.ssrc);
657 sent_media_ = true;
658 }
659
660 if (header_extensions_enabled_) {
661 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
662 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
663 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
664 }
665
brandtr0c5a1542016-11-23 04:42:26 -0800666 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800667 observation_complete_.Set();
668 }
669
670 return SEND_PACKET;
671 }
672
673 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
674 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
675 // Therefore we need some network delay.
676 const int kNetworkDelayMs = 100;
677 FakeNetworkPipe::Config config;
brandtrd654a9b2016-12-05 05:38:19 -0800678 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800679 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700680 return new test::PacketTransport(
681 sender_call, this, test::PacketTransport::kSender,
682 VideoSendStreamTest::payload_type_map_, config);
brandtr39f97292016-11-16 22:57:50 -0800683 }
684
685 void ModifyVideoConfigs(
686 VideoSendStream::Config* send_config,
687 std::vector<VideoReceiveStream::Config>* receive_configs,
688 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800689 if (use_nack_) {
690 send_config->rtp.nack.rtp_history_ms =
691 (*receive_configs)[0].rtp.nack.rtp_history_ms =
692 VideoSendStreamTest::kNackRtpHistoryMs;
693 }
brandtr696c9c62016-12-19 05:47:28 -0800694 send_config->encoder_settings.encoder = encoder_;
brandtr39f97292016-11-16 22:57:50 -0800695 send_config->encoder_settings.payload_name = payload_name_;
696 if (header_extensions_enabled_) {
697 send_config->rtp.extensions.push_back(RtpExtension(
698 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
699 send_config->rtp.extensions.push_back(RtpExtension(
700 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800701 } else {
702 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800703 }
704 }
705
706 void PerformTest() override {
707 EXPECT_TRUE(Wait())
708 << "Timed out waiting for FlexFEC and/or media packets.";
709 }
710
brandtr696c9c62016-12-19 05:47:28 -0800711 VideoEncoder* const encoder_;
712 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800713 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800714 bool sent_media_;
715 bool sent_flexfec_;
716 bool header_extensions_enabled_;
717};
718
brandtrd654a9b2016-12-05 05:38:19 -0800719TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800720 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
721 FlexfecObserver test(false, false, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800722 RunBaseTest(&test);
723}
724
725TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800726 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
727 FlexfecObserver test(false, true, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800728 RunBaseTest(&test);
729}
730
brandtr39f97292016-11-16 22:57:50 -0800731TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800732 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
733 FlexfecObserver test(true, false, "VP8", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800734 RunBaseTest(&test);
735}
736
brandtr39f97292016-11-16 22:57:50 -0800737#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800738TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800739 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
740 FlexfecObserver test(false, false, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800741 RunBaseTest(&test);
742}
743
brandtrd654a9b2016-12-05 05:38:19 -0800744TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800745 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
746 FlexfecObserver test(false, true, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800747 RunBaseTest(&test);
748}
749#endif // defined(RTC_DISABLE_VP9)
750
brandtrd654a9b2016-12-05 05:38:19 -0800751TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
brandtr696c9c62016-12-19 05:47:28 -0800752 std::unique_ptr<VideoEncoder> encoder(
753 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
754 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800755 RunBaseTest(&test);
756}
757
brandtrd654a9b2016-12-05 05:38:19 -0800758TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
brandtr696c9c62016-12-19 05:47:28 -0800759 std::unique_ptr<VideoEncoder> encoder(
760 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
761 FlexfecObserver test(false, true, "H264", encoder.get());
762 RunBaseTest(&test);
763}
764
brandtre78d2662017-01-16 05:57:16 -0800765TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800766 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800767 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800768 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800769 RunBaseTest(&test);
770}
771
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000772void VideoSendStreamTest::TestNackRetransmission(
773 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000774 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000775 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000776 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000777 explicit NackObserver(uint32_t retransmit_ssrc,
778 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000779 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000780 send_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000781 retransmit_ssrc_(retransmit_ssrc),
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000782 retransmit_payload_type_(retransmit_payload_type),
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000783 nacked_sequence_number_(-1) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000784 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000785
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000786 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000787 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000788 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000789 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000790
791 // Nack second packet after receiving the third one.
792 if (++send_count_ == 3) {
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000793 uint16_t nack_sequence_number = header.sequenceNumber - 1;
794 nacked_sequence_number_ = nack_sequence_number;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000795 NullReceiveStatistics null_stats;
Peter Boströmac547a62015-09-17 23:03:57 +0200796 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), &null_stats,
terelius429c3452016-01-21 05:42:04 -0800797 nullptr, nullptr, transport_adapter_.get());
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000798
pbosda903ea2015-10-02 02:36:56 -0700799 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100800 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000801
802 RTCPSender::FeedbackState feedback_state;
803
804 EXPECT_EQ(0,
805 rtcp_sender.SendRTCP(
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000806 feedback_state, kRtcpNack, 1, &nack_sequence_number));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000807 }
808
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000809 uint16_t sequence_number = header.sequenceNumber;
810
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000811 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100812 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
813 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000814 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000815 const uint8_t* rtx_header = packet + header.headerLength;
816 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
817 }
818
819 if (sequence_number == nacked_sequence_number_) {
820 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000821 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
Peter Boström5811a392015-12-10 13:02:50 +0100822 observation_complete_.Set();
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000823 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000824
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000825 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000826 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000827
stefanff483612015-12-21 03:14:00 -0800828 void ModifyVideoConfigs(
829 VideoSendStream::Config* send_config,
830 std::vector<VideoReceiveStream::Config>* receive_configs,
831 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700832 transport_adapter_.reset(
833 new internal::TransportAdapter(send_config->send_transport));
834 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000835 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000836 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100837 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000838 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
839 }
840
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000841 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100842 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000843 }
844
kwiberg27f982b2016-03-01 11:52:33 -0800845 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000846 int send_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000847 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000848 uint8_t retransmit_payload_type_;
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000849 int nacked_sequence_number_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000850 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000851
stefane74eef12016-01-08 06:47:13 -0800852 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000853}
854
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000855TEST_F(VideoSendStreamTest, RetransmitsNack) {
856 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100857 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000858}
859
860TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
861 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000862 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000863}
864
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000865void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
866 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000867 // Use a fake encoder to output a frame of every size in the range [90, 290],
868 // for each size making sure that the exact number of payload bytes received
869 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000870 static const size_t kMaxPacketSize = 128;
871 static const size_t start = 90;
872 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000873
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000874 // Observer that verifies that the expected number of packets and bytes
875 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000876 class FrameFragmentationTest : public test::SendTest,
877 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000878 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000879 FrameFragmentationTest(size_t max_packet_size,
880 size_t start_size,
881 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000882 bool test_generic_packetization,
883 bool use_fec)
884 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000885 encoder_(stop),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000886 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000887 stop_size_(stop_size),
888 test_generic_packetization_(test_generic_packetization),
889 use_fec_(use_fec),
890 packet_count_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000891 accumulated_size_(0),
892 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000893 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000894 current_size_rtp_(start_size),
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000895 current_size_frame_(static_cast<int32_t>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000896 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000897 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700898 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000899 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000900
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000901 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000902 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000903 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000904 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000905 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000906
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000907 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000908
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000909 if (use_fec_) {
910 uint8_t payload_type = packet[header.headerLength];
911 bool is_fec = header.payloadType == kRedPayloadType &&
912 payload_type == kUlpfecPayloadType;
913 if (is_fec) {
914 fec_packet_received_ = true;
915 return SEND_PACKET;
916 }
917 }
918
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000919 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000920
921 if (use_fec_)
922 TriggerLossReport(header);
923
924 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200925 size_t overhead = header.headerLength + header.paddingLength;
926 // Only remove payload header and RED header if the packet actually
927 // contains payload.
928 if (length > overhead) {
929 overhead += (1 /* Generic header */);
930 if (use_fec_)
931 overhead += 1; // RED for FEC header.
932 }
933 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000934 accumulated_payload_ += length - overhead;
935 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000936
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000937 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000938 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000939 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
940 // With FEC enabled, frame size is incremented asynchronously, so
941 // "old" frames one byte too small may arrive. Accept, but don't
942 // increase expected frame size.
943 accumulated_size_ = 0;
944 accumulated_payload_ = 0;
945 return SEND_PACKET;
946 }
947
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000948 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000949 if (test_generic_packetization_) {
950 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
951 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000952
953 // Last packet of frame; reset counters.
954 accumulated_size_ = 0;
955 accumulated_payload_ = 0;
956 if (current_size_rtp_ == stop_size_) {
957 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +0100958 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000959 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000960 // Increase next expected frame size. If testing with FEC, make sure
961 // a FEC packet has been received for this frame size before
962 // proceeding, to make sure that redundancy packets don't exceed
963 // size limit.
964 if (!use_fec_) {
965 ++current_size_rtp_;
966 } else if (fec_packet_received_) {
967 fec_packet_received_ = false;
968 ++current_size_rtp_;
969 ++current_size_frame_;
970 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000971 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000972 }
973
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000974 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000975 }
976
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000977 void TriggerLossReport(const RTPHeader& header) {
978 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -0700979 const int kLossPercent = 5;
980 if (packet_count_++ % (100 / kLossPercent) != 0) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000981 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -0700982 kVideoSendSsrcs[0], header.sequenceNumber,
983 (packet_count_ * (100 - kLossPercent)) / 100, // Cumulative lost.
984 static_cast<uint8_t>((255 * kLossPercent) / 100)); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +0200985 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -0800986 &lossy_receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -0700987 transport_adapter_.get());
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000988
pbosda903ea2015-10-02 02:36:56 -0700989 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100990 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000991
992 RTCPSender::FeedbackState feedback_state;
993
994 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
995 }
996 }
997
nisseef8b61e2016-04-29 06:09:15 -0700998 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000999 // Increase frame size for next encoded frame, in the context of the
1000 // encoder thread.
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001001 if (!use_fec_ &&
1002 current_size_frame_.Value() < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001003 ++current_size_frame_;
1004 }
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001005 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_.Value()));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001006 }
1007
Stefan Holmere5904162015-03-26 11:11:06 +01001008 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07001009 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01001010 const int kMinBitrateBps = 30000;
1011 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
1012 return config;
1013 }
1014
stefanff483612015-12-21 03:14:00 -08001015 void ModifyVideoConfigs(
1016 VideoSendStream::Config* send_config,
1017 std::vector<VideoReceiveStream::Config>* receive_configs,
1018 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001019 transport_adapter_.reset(
1020 new internal::TransportAdapter(send_config->send_transport));
1021 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001022 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001023 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1024 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001025 }
1026
1027 if (!test_generic_packetization_)
1028 send_config->encoder_settings.payload_name = "VP8";
1029
1030 send_config->encoder_settings.encoder = &encoder_;
1031 send_config->rtp.max_packet_size = kMaxPacketSize;
1032 send_config->post_encode_callback = this;
1033
Erik Språng95261872015-04-10 11:58:49 +02001034 // Make sure there is at least one extension header, to make the RTP
1035 // header larger than the base length of 12 bytes.
1036 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001037
1038 // Setup screen content disables frame dropping which makes this easier.
1039 class VideoStreamFactory
1040 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1041 public:
1042 explicit VideoStreamFactory(size_t num_temporal_layers)
1043 : num_temporal_layers_(num_temporal_layers) {
1044 EXPECT_GT(num_temporal_layers, 0u);
1045 }
1046
1047 private:
1048 std::vector<VideoStream> CreateEncoderStreams(
1049 int width,
1050 int height,
1051 const VideoEncoderConfig& encoder_config) override {
1052 std::vector<VideoStream> streams =
1053 test::CreateVideoStreams(width, height, encoder_config);
1054 for (VideoStream& stream : streams) {
1055 stream.temporal_layer_thresholds_bps.resize(num_temporal_layers_ -
1056 1);
1057 }
1058 return streams;
1059 }
1060 const size_t num_temporal_layers_;
1061 };
1062
1063 encoder_config->video_stream_factory =
1064 new rtc::RefCountedObject<VideoStreamFactory>(2);
1065 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001066 }
1067
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001068 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001069 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001070 }
1071
kwiberg27f982b2016-03-01 11:52:33 -08001072 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001073 test::ConfigurableFrameSizeEncoder encoder_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001074
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001075 const size_t max_packet_size_;
1076 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001077 const bool test_generic_packetization_;
1078 const bool use_fec_;
1079
1080 uint32_t packet_count_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001081 size_t accumulated_size_;
1082 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001083 bool fec_packet_received_;
1084
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001085 size_t current_size_rtp_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001086 Atomic32 current_size_frame_;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001087 };
1088
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001089 // Don't auto increment if FEC is used; continue sending frame size until
1090 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001091 FrameFragmentationTest test(
1092 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001093
stefane74eef12016-01-08 06:47:13 -08001094 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001095}
1096
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001097// TODO(sprang): Is there any way of speeding up these tests?
1098TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
1099 TestPacketFragmentationSize(kGeneric, false);
1100}
1101
1102TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
1103 TestPacketFragmentationSize(kGeneric, true);
1104}
1105
1106TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
1107 TestPacketFragmentationSize(kVP8, false);
1108}
1109
1110TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
1111 TestPacketFragmentationSize(kVP8, true);
1112}
1113
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001114// The test will go through a number of phases.
1115// 1. Start sending packets.
1116// 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 +00001117// suspend the stream.
1118// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001119// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001120// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001121// When the stream is detected again, and the stats show that the stream
1122// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001123TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1124 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001125
nissed30a1112016-04-18 05:15:22 -07001126 class RembObserver : public test::SendTest,
1127 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001128 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001129 RembObserver()
1130 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001131 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001132 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001133 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001134 rtp_count_(0),
1135 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001136 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001137 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001138 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001139
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001140 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001141 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001142 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001143 ++rtp_count_;
1144 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001145 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001146 last_sequence_number_ = header.sequenceNumber;
1147
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001148 if (test_state_ == kBeforeSuspend) {
1149 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001150 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001151 test_state_ = kDuringSuspend;
1152 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001153 if (header.paddingLength == 0) {
1154 // Received non-padding packet during suspension period. Reset the
1155 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001156 suspended_frame_count_ = 0;
1157 }
stefanf116bd02015-10-27 08:29:42 -07001158 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001159 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001160 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001161 // Non-padding packet observed. Test is almost complete. Will just
1162 // have to wait for the stats to change.
1163 test_state_ = kWaitingForStats;
1164 }
stefanf116bd02015-10-27 08:29:42 -07001165 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001166 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001167 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001168 if (stats.suspended == false) {
1169 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001170 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001171 }
stefanf116bd02015-10-27 08:29:42 -07001172 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001173 }
1174
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001175 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001176 }
1177
perkj26091b12016-09-01 01:17:40 -07001178 // This method implements the rtc::VideoSinkInterface. This is called when
1179 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001180 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001181 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001182 if (test_state_ == kDuringSuspend &&
1183 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001184 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001185 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001186 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001187 test_state_ = kWaitingForPacket;
1188 }
1189 }
1190
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001191 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001192 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001193 low_remb_bps_ = value;
1194 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001195
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001196 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001197 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001198 high_remb_bps_ = value;
1199 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001200
stefanff483612015-12-21 03:14:00 -08001201 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001202 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001203 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001204 stream_ = send_stream;
1205 }
1206
stefanff483612015-12-21 03:14:00 -08001207 void ModifyVideoConfigs(
1208 VideoSendStream::Config* send_config,
1209 std::vector<VideoReceiveStream::Config>* receive_configs,
1210 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001211 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001212 transport_adapter_.reset(
1213 new internal::TransportAdapter(send_config->send_transport));
1214 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001215 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001216 send_config->pre_encode_callback = this;
1217 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001218 int min_bitrate_bps =
1219 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001220 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001221 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001222 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001223 min_bitrate_bps + threshold_window + 5000);
1224 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1225 }
1226
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001227 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001228 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001229 }
1230
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001231 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001232 kBeforeSuspend,
1233 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001234 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001235 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001236 };
1237
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001238 virtual void SendRtcpFeedback(int remb_value)
1239 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001240 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1241 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001242 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -07001243 transport_adapter_.get());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001244
pbosda903ea2015-10-02 02:36:56 -07001245 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001246 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001247 if (remb_value > 0) {
1248 rtcp_sender.SetREMBStatus(true);
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001249 rtcp_sender.SetREMBData(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001250 }
1251 RTCPSender::FeedbackState feedback_state;
1252 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1253 }
1254
kwiberg27f982b2016-03-01 11:52:33 -08001255 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001256 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001257 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001258
Peter Boströmf2f82832015-05-01 13:00:41 +02001259 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001260 TestState test_state_ GUARDED_BY(crit_);
1261 int rtp_count_ GUARDED_BY(crit_);
1262 int last_sequence_number_ GUARDED_BY(crit_);
1263 int suspended_frame_count_ GUARDED_BY(crit_);
1264 int low_remb_bps_ GUARDED_BY(crit_);
1265 int high_remb_bps_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001266 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001267
stefane74eef12016-01-08 06:47:13 -08001268 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001269}
1270
perkj71ee44c2016-06-15 00:47:53 -07001271// This test that padding stops being send after a while if the Camera stops
1272// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001273TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001274 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001275 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001276 NoPaddingWhenVideoIsMuted()
1277 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001278 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001279 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001280 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +00001281 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001282
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001283 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001284 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001285 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001286 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001287
1288 RTPHeader header;
1289 parser_->Parse(packet, length, &header);
1290 const bool only_padding =
1291 header.headerLength + header.paddingLength == length;
1292
1293 if (test_state_ == kBeforeStopCapture) {
1294 capturer_->Stop();
1295 test_state_ = kWaitingForPadding;
1296 } else if (test_state_ == kWaitingForPadding && only_padding) {
1297 test_state_ = kWaitingForNoPackets;
1298 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1299 only_padding) {
1300 observation_complete_.Set();
1301 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001302 return SEND_PACKET;
1303 }
1304
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001305 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001306 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001307 const int kNoPacketsThresholdMs = 2000;
1308 if (test_state_ == kWaitingForNoPackets &&
1309 (last_packet_time_ms_ > 0 &&
1310 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1311 kNoPacketsThresholdMs)) {
1312 capturer_->Start();
1313 test_state_ = kWaitingForPaddingAfterCameraRestart;
1314 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001315 return SEND_PACKET;
1316 }
1317
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001318 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001319
nisseef8b61e2016-04-29 06:09:15 -07001320 void OnFrameGeneratorCapturerCreated(
1321 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001322 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001323 capturer_ = frame_generator_capturer;
1324 }
1325
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001326 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001327 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001328 << "Timed out while waiting for RTP packets to stop being sent.";
1329 }
1330
perkj71ee44c2016-06-15 00:47:53 -07001331 enum TestState {
1332 kBeforeStopCapture,
1333 kWaitingForPadding,
1334 kWaitingForNoPackets,
1335 kWaitingForPaddingAfterCameraRestart
1336 };
1337
1338 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001339 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001340 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001341 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001342 int64_t last_packet_time_ms_ GUARDED_BY(crit_);
1343 test::FrameGeneratorCapturer* capturer_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001344 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001345
stefane74eef12016-01-08 06:47:13 -08001346 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001347}
1348
isheriffcc5903e2016-10-04 08:29:38 -07001349TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1350 const int kCapacityKbps = 10000; // 10 Mbps
1351 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1352 public:
1353 PaddingIsPrimarilyRetransmissions()
1354 : EndToEndTest(kDefaultTimeoutMs),
1355 clock_(Clock::GetRealTimeClock()),
1356 padding_length_(0),
1357 total_length_(0),
1358 call_(nullptr) {}
1359
1360 private:
1361 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1362 call_ = sender_call;
1363 }
1364
1365 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1366 rtc::CritScope lock(&crit_);
1367
1368 RTPHeader header;
1369 parser_->Parse(packet, length, &header);
1370 padding_length_ += header.paddingLength;
1371 total_length_ += length;
1372 return SEND_PACKET;
1373 }
1374
1375 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
1376 const int kNetworkDelayMs = 50;
1377 FakeNetworkPipe::Config config;
1378 config.loss_percent = 10;
1379 config.link_capacity_kbps = kCapacityKbps;
1380 config.queue_delay_ms = kNetworkDelayMs;
1381 return new test::PacketTransport(sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -07001382 test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -07001383 payload_type_map_, config);
isheriffcc5903e2016-10-04 08:29:38 -07001384 }
1385
1386 void ModifyVideoConfigs(
1387 VideoSendStream::Config* send_config,
1388 std::vector<VideoReceiveStream::Config>* receive_configs,
1389 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001390 // Turn on RTX.
1391 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1392 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001393 }
1394
1395 void PerformTest() override {
1396 // TODO(isheriff): Some platforms do not ramp up as expected to full
1397 // capacity due to packet scheduling delays. Fix that before getting
1398 // rid of this.
1399 SleepMs(5000);
1400 {
1401 rtc::CritScope lock(&crit_);
1402 // Expect padding to be a small percentage of total bytes sent.
1403 EXPECT_LT(padding_length_, .1 * total_length_);
1404 }
1405 }
1406
1407 rtc::CriticalSection crit_;
1408 Clock* const clock_;
1409 size_t padding_length_ GUARDED_BY(crit_);
1410 size_t total_length_ GUARDED_BY(crit_);
1411 Call* call_;
1412 } test;
1413
1414 RunBaseTest(&test);
1415}
1416
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001417// This test first observes "high" bitrate use at which point it sends a REMB to
1418// indicate that it should be lowered significantly. The test then observes that
1419// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1420// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001421//
1422// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1423// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001424TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1425 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001426 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001427 static const int kRembBitrateBps = 80000;
1428 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001429 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001430 public:
1431 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001432 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001433 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1434 stream_(nullptr),
1435 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001436
1437 private:
nisseef8b61e2016-04-29 06:09:15 -07001438 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001439 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001440 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001441
1442 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001443 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001444 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001445 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001446 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001447 if (!stats.substreams.empty()) {
1448 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001449 int total_bitrate_bps =
1450 stats.substreams.begin()->second.total_bitrate_bps;
1451 test::PrintResult("bitrate_stats_",
1452 "min_transmit_bitrate_low_remb",
1453 "bitrate_bps",
1454 static_cast<size_t>(total_bitrate_bps),
1455 "bps",
1456 false);
1457 if (total_bitrate_bps > kHighBitrateBps) {
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001458 rtp_rtcp_->SetREMBData(kRembBitrateBps,
1459 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001460 rtp_rtcp_->Process();
1461 bitrate_capped_ = true;
1462 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001463 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001464 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001465 }
1466 }
stefanf116bd02015-10-27 08:29:42 -07001467 // Packets don't have to be delivered since the test is the receiver.
1468 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001469 }
1470
stefanff483612015-12-21 03:14:00 -08001471 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001472 VideoSendStream* send_stream,
1473 const std::vector<VideoReceiveStream*>& receive_streams) override {
1474 stream_ = send_stream;
1475 RtpRtcp::Configuration config;
1476 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001477 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001478 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
1479 rtp_rtcp_->SetREMBStatus(true);
1480 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001481 }
1482
stefanff483612015-12-21 03:14:00 -08001483 void ModifyVideoConfigs(
1484 VideoSendStream::Config* send_config,
1485 std::vector<VideoReceiveStream::Config>* receive_configs,
1486 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001487 feedback_transport_.reset(
1488 new internal::TransportAdapter(send_config->send_transport));
1489 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001490 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001491 }
1492
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001493 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001494 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001495 << "Timeout while waiting for low bitrate stats after REMB.";
1496 }
1497
kwiberg27f982b2016-03-01 11:52:33 -08001498 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1499 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001500 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001501 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001502 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001503 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001504
stefane74eef12016-01-08 06:47:13 -08001505 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001506}
1507
Stefan Holmer280de9e2016-09-30 10:06:51 +02001508TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1509 static const int kStartBitrateBps = 300000;
1510 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001511 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001512 class ChangingNetworkRouteTest : public test::EndToEndTest {
1513 public:
Stefan Holmerbe402962016-07-08 16:16:41 +02001514 ChangingNetworkRouteTest()
Stefan Holmer280de9e2016-09-30 10:06:51 +02001515 : EndToEndTest(test::CallTest::kDefaultTimeoutMs), call_(nullptr) {
1516 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1517 kRtpExtensionTransportSequenceNumber, kExtensionId));
1518 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001519
1520 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1521 call_ = sender_call;
1522 }
1523
Stefan Holmer280de9e2016-09-30 10:06:51 +02001524 void ModifyVideoConfigs(
1525 VideoSendStream::Config* send_config,
1526 std::vector<VideoReceiveStream::Config>* receive_configs,
1527 VideoEncoderConfig* encoder_config) override {
1528 send_config->rtp.extensions.clear();
1529 send_config->rtp.extensions.push_back(RtpExtension(
1530 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1531 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1532 (*receive_configs)[0].rtp.transport_cc = true;
1533 }
1534
1535 void ModifyAudioConfigs(
1536 AudioSendStream::Config* send_config,
1537 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1538 send_config->rtp.extensions.clear();
1539 send_config->rtp.extensions.push_back(RtpExtension(
1540 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1541 (*receive_configs)[0].rtp.extensions.clear();
1542 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1543 (*receive_configs)[0].rtp.transport_cc = true;
1544 }
1545
Stefan Holmerbe402962016-07-08 16:16:41 +02001546 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1547 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1548 observation_complete_.Set();
1549 }
1550
1551 return SEND_PACKET;
1552 }
1553
1554 void PerformTest() override {
1555 rtc::NetworkRoute new_route(true, 10, 20, -1);
1556 call_->OnNetworkRouteChanged("transport", new_route);
1557 Call::Config::BitrateConfig bitrate_config;
1558 bitrate_config.start_bitrate_bps = kStartBitrateBps;
1559 call_->SetBitrateConfig(bitrate_config);
1560 EXPECT_TRUE(Wait())
1561 << "Timed out while waiting for start bitrate to be exceeded.";
1562
1563 bitrate_config.start_bitrate_bps = -1;
1564 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
1565 call_->SetBitrateConfig(bitrate_config);
1566 // TODO(holmer): We should set the last sent packet id here and verify
1567 // that we correctly ignore any packet loss reported prior to that id.
1568 ++new_route.local_network_id;
1569 call_->OnNetworkRouteChanged("transport", new_route);
stefan01bbc3c2016-10-25 04:19:48 -07001570 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
Stefan Holmerbe402962016-07-08 16:16:41 +02001571 }
1572
1573 private:
1574 Call* call_;
1575 } test;
1576
1577 RunBaseTest(&test);
1578}
1579
michaelt79e05882016-11-08 02:50:09 -08001580TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
1581 class ChangingTransportOverheadTest : public test::EndToEndTest {
1582 public:
1583 ChangingTransportOverheadTest()
1584 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1585 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001586 packets_sent_(0),
1587 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001588
1589 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1590 call_ = sender_call;
1591 }
1592
1593 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001594 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001595 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001596 if (++packets_sent_ < 100)
1597 return SEND_PACKET;
1598 observation_complete_.Set();
1599 return SEND_PACKET;
1600 }
1601
michaelta3328772016-11-29 09:25:03 -08001602 void ModifyVideoConfigs(
1603 VideoSendStream::Config* send_config,
1604 std::vector<VideoReceiveStream::Config>* receive_configs,
1605 VideoEncoderConfig* encoder_config) override {
1606 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1607 }
1608
michaelt79e05882016-11-08 02:50:09 -08001609 void PerformTest() override {
michaelta3328772016-11-29 09:25:03 -08001610 transport_overhead_ = 100;
michaelt79e05882016-11-08 02:50:09 -08001611 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1612 transport_overhead_);
1613 EXPECT_TRUE(Wait());
sprang21253fc2017-02-27 03:35:47 -08001614 {
1615 rtc::CritScope cs(&lock_);
1616 packets_sent_ = 0;
1617 }
michaelta3328772016-11-29 09:25:03 -08001618 transport_overhead_ = 500;
michaelt79e05882016-11-08 02:50:09 -08001619 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1620 transport_overhead_);
1621 EXPECT_TRUE(Wait());
1622 }
1623
1624 private:
1625 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001626 rtc::CriticalSection lock_;
1627 int packets_sent_ GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001628 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001629 const size_t kMaxRtpPacketSize = 1000;
michaelt79e05882016-11-08 02:50:09 -08001630 } test;
1631
1632 RunBaseTest(&test);
1633}
1634
sprangf24a0642017-02-28 13:23:26 -08001635// Test class takes takes as argument a switch selecting if type switch should
1636// occur and a function pointer to reset the send stream. This is necessary
1637// since you cannot change the content type of a VideoSendStream, you need to
1638// recreate it. Stopping and recreating the stream can only be done on the main
1639// thread and in the context of VideoSendStreamTest (not BaseTest).
1640template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001641class MaxPaddingSetTest : public test::SendTest {
1642 public:
1643 static const uint32_t kMinTransmitBitrateBps = 400000;
1644 static const uint32_t kActualEncodeBitrateBps = 40000;
1645 static const uint32_t kMinPacketsToSend = 50;
1646
sprangf24a0642017-02-28 13:23:26 -08001647 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001648 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001649 content_switch_event_(false, false),
sprang9c0b5512016-07-06 00:54:28 -07001650 call_(nullptr),
1651 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001652 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001653 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001654 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001655 stream_resetter_(stream_reset_fun) {
1656 RTC_DCHECK(stream_resetter_);
1657 }
sprang9c0b5512016-07-06 00:54:28 -07001658
1659 void OnVideoStreamsCreated(
1660 VideoSendStream* send_stream,
1661 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001662 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001663 send_stream_ = send_stream;
1664 }
1665
1666 void ModifyVideoConfigs(
1667 VideoSendStream::Config* send_config,
1668 std::vector<VideoReceiveStream::Config>* receive_configs,
1669 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001670 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001671 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001672 encoder_config->min_transmit_bitrate_bps = 0;
1673 encoder_config->content_type =
1674 VideoEncoderConfig::ContentType::kRealtimeVideo;
1675 } else {
1676 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1677 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1678 }
sprangf24a0642017-02-28 13:23:26 -08001679 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001680 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001681 }
1682
1683 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1684 call_ = sender_call;
1685 }
1686
1687 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1688 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001689 if (running_without_padding_)
1690 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1691
1692 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1693 // we have reliable data.
1694 if (++packets_sent_ < kMinPacketsToSend)
1695 return SEND_PACKET;
1696
1697 if (running_without_padding_) {
1698 // We've sent kMinPacketsToSend packets with default configuration, switch
1699 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001700 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001701 packets_sent_ = 0;
1702 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1703 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001704 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001705 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001706 return SEND_PACKET;
1707 }
1708
1709 // Make sure the pacer has been configured with a min transmit bitrate.
1710 if (call_->GetStats().max_padding_bitrate_bps > 0)
1711 observation_complete_.Set();
1712
1713 return SEND_PACKET;
1714 }
1715
1716 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001717 if (RunningWithoutPadding()) {
1718 ASSERT_TRUE(
1719 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001720 (*stream_resetter_)(send_stream_config_, encoder_config_);
1721 }
1722
sprang9c0b5512016-07-06 00:54:28 -07001723 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1724 }
1725
1726 private:
sprangf24a0642017-02-28 13:23:26 -08001727 bool RunningWithoutPadding() const {
1728 rtc::CritScope lock(&crit_);
1729 return running_without_padding_;
1730 }
1731
sprang9c0b5512016-07-06 00:54:28 -07001732 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001733 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001734 Call* call_;
sprangf24a0642017-02-28 13:23:26 -08001735 VideoSendStream* send_stream_ GUARDED_BY(crit_);
1736 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001737 VideoEncoderConfig encoder_config_;
1738 uint32_t packets_sent_ GUARDED_BY(crit_);
1739 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001740 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001741};
1742
1743TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001744 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1745 const VideoEncoderConfig& encoder_config) {};
1746 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001747 RunBaseTest(&test);
1748}
1749
1750TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001751 // Function for removing and recreating the send stream with a new config.
1752 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1753 const VideoEncoderConfig& encoder_config) {
1754 Stop();
1755 sender_call_->DestroyVideoSendStream(video_send_stream_);
1756 video_send_config_ = send_stream_config.Copy();
1757 video_encoder_config_ = encoder_config.Copy();
1758 video_send_stream_ = sender_call_->CreateVideoSendStream(
1759 video_send_config_.Copy(), video_encoder_config_.Copy());
1760 video_send_stream_->SetSource(
1761 frame_generator_capturer_.get(),
1762 VideoSendStream::DegradationPreference::kMaintainResolution);
1763 Start();
1764 };
1765 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001766 RunBaseTest(&test);
1767}
1768
perkjfa10b552016-10-02 23:45:26 -07001769// This test verifies that new frame sizes reconfigures encoders even though not
1770// (yet) sending. The purpose of this is to permit encoding as quickly as
1771// possible once we start sending. Likely the frames being input are from the
1772// same source that will be sent later, which just means that we're ready
1773// earlier.
1774TEST_F(VideoSendStreamTest,
1775 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1776 class EncoderObserver : public test::FakeEncoder {
1777 public:
1778 EncoderObserver()
1779 : FakeEncoder(Clock::GetRealTimeClock()),
1780 init_encode_called_(false, false),
1781 number_of_initializations_(0),
1782 last_initialized_frame_width_(0),
1783 last_initialized_frame_height_(0) {}
1784
1785 void WaitForResolution(int width, int height) {
1786 {
1787 rtc::CritScope lock(&crit_);
1788 if (last_initialized_frame_width_ == width &&
1789 last_initialized_frame_height_ == height) {
1790 return;
1791 }
1792 }
Erik Språng08127a92016-11-16 16:41:30 +01001793 EXPECT_TRUE(
1794 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001795 {
1796 rtc::CritScope lock(&crit_);
1797 EXPECT_EQ(width, last_initialized_frame_width_);
1798 EXPECT_EQ(height, last_initialized_frame_height_);
1799 }
1800 }
1801
1802 private:
1803 int32_t InitEncode(const VideoCodec* config,
1804 int32_t number_of_cores,
1805 size_t max_payload_size) override {
1806 rtc::CritScope lock(&crit_);
1807 last_initialized_frame_width_ = config->width;
1808 last_initialized_frame_height_ = config->height;
1809 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001810 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001811 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1812 }
1813
1814 int32_t Encode(const VideoFrame& input_image,
1815 const CodecSpecificInfo* codec_specific_info,
1816 const std::vector<FrameType>* frame_types) override {
1817 ADD_FAILURE()
1818 << "Unexpected Encode call since the send stream is not started";
1819 return 0;
1820 }
1821
1822 rtc::CriticalSection crit_;
1823 rtc::Event init_encode_called_;
1824 size_t number_of_initializations_ GUARDED_BY(&crit_);
1825 int last_initialized_frame_width_ GUARDED_BY(&crit_);
1826 int last_initialized_frame_height_ GUARDED_BY(&crit_);
1827 };
1828
philipel4fb651d2017-04-10 03:54:05 -07001829 CreateSenderCall(Call::Config(event_log_.get()));
perkjfa10b552016-10-02 23:45:26 -07001830 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001831 CreateSendConfig(1, 0, 0, &transport);
perkjfa10b552016-10-02 23:45:26 -07001832 EncoderObserver encoder;
1833 video_send_config_.encoder_settings.encoder = &encoder;
1834 CreateVideoStreams();
1835 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1836 kDefaultHeight);
1837 frame_generator_capturer_->Start();
1838
1839 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
1840 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1841 kDefaultHeight * 2);
1842 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
1843 DestroyStreams();
1844}
1845
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001846TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1847 class StartBitrateObserver : public test::FakeEncoder {
1848 public:
1849 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001850 : FakeEncoder(Clock::GetRealTimeClock()),
1851 start_bitrate_changed_(false, false),
1852 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001853 int32_t InitEncode(const VideoCodec* config,
1854 int32_t number_of_cores,
1855 size_t max_payload_size) override {
1856 rtc::CritScope lock(&crit_);
1857 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001858 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001859 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1860 }
1861
1862 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1863 rtc::CritScope lock(&crit_);
1864 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001865 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001866 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1867 }
1868
1869 int GetStartBitrateKbps() const {
1870 rtc::CritScope lock(&crit_);
1871 return start_bitrate_kbps_;
1872 }
1873
pbos14fe7082016-04-20 06:35:56 -07001874 bool WaitForStartBitrate() {
1875 return start_bitrate_changed_.Wait(
1876 VideoSendStreamTest::kDefaultTimeoutMs);
1877 }
1878
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001879 private:
pbos5ad935c2016-01-25 03:52:44 -08001880 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001881 rtc::Event start_bitrate_changed_;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001882 int start_bitrate_kbps_ GUARDED_BY(crit_);
1883 };
1884
philipel4fb651d2017-04-10 03:54:05 -07001885 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001886
solenberg4fbae2b2015-08-28 04:07:10 -07001887 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001888 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001889
1890 Call::Config::BitrateConfig bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07001891 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001892 sender_call_->SetBitrateConfig(bitrate_config);
1893
1894 StartBitrateObserver encoder;
stefanff483612015-12-21 03:14:00 -08001895 video_send_config_.encoder_settings.encoder = &encoder;
perkjfa10b552016-10-02 23:45:26 -07001896 // Since this test does not use a capturer, set |internal_source| = true.
1897 // Encoder configuration is otherwise updated on the next video frame.
1898 video_send_config_.encoder_settings.internal_source = true;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001899
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001900 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001901
pbos14fe7082016-04-20 06:35:56 -07001902 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07001903 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001904 encoder.GetStartBitrateKbps());
1905
perkjfa10b552016-10-02 23:45:26 -07001906 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07001907 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001908
1909 // New bitrate should be reconfigured above the previous max. As there's no
1910 // network connection this shouldn't be flaky, as no bitrate should've been
1911 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07001912 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001913 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
1914 encoder.GetStartBitrateKbps());
1915
1916 DestroyStreams();
1917}
1918
perkj57c21f92016-06-17 07:27:16 -07001919// This test that if the encoder use an internal source, VideoEncoder::SetRates
1920// will be called with zero bitrate during initialization and that
1921// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
1922// with zero bitrate.
1923TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
1924 class StartStopBitrateObserver : public test::FakeEncoder {
1925 public:
1926 StartStopBitrateObserver()
1927 : FakeEncoder(Clock::GetRealTimeClock()),
1928 encoder_init_(false, false),
Erik Språng08127a92016-11-16 16:41:30 +01001929 bitrate_changed_(false, false) {}
perkj57c21f92016-06-17 07:27:16 -07001930 int32_t InitEncode(const VideoCodec* config,
1931 int32_t number_of_cores,
1932 size_t max_payload_size) override {
1933 rtc::CritScope lock(&crit_);
perkj57c21f92016-06-17 07:27:16 -07001934 encoder_init_.Set();
1935 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1936 }
1937
Erik Språng08127a92016-11-16 16:41:30 +01001938 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
1939 uint32_t framerate) override {
perkj57c21f92016-06-17 07:27:16 -07001940 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01001941 bitrate_kbps_ = rtc::Optional<int>(bitrate.get_sum_kbps());
perkj57c21f92016-06-17 07:27:16 -07001942 bitrate_changed_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01001943 return FakeEncoder::SetRateAllocation(bitrate, framerate);
perkj57c21f92016-06-17 07:27:16 -07001944 }
1945
1946 bool WaitForEncoderInit() {
1947 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1948 }
Erik Språng08127a92016-11-16 16:41:30 +01001949
1950 bool WaitBitrateChanged(bool non_zero) {
1951 do {
1952 rtc::Optional<int> bitrate_kbps;
1953 {
1954 rtc::CritScope lock(&crit_);
1955 bitrate_kbps = bitrate_kbps_;
1956 }
1957 if (!bitrate_kbps)
1958 continue;
1959
1960 if ((non_zero && *bitrate_kbps > 0) ||
1961 (!non_zero && *bitrate_kbps == 0)) {
1962 return true;
1963 }
1964 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
1965 return false;
perkj57c21f92016-06-17 07:27:16 -07001966 }
1967
1968 private:
1969 rtc::CriticalSection crit_;
1970 rtc::Event encoder_init_;
1971 rtc::Event bitrate_changed_;
Erik Språng08127a92016-11-16 16:41:30 +01001972 rtc::Optional<int> bitrate_kbps_ GUARDED_BY(crit_);
perkj57c21f92016-06-17 07:27:16 -07001973 };
1974
philipel4fb651d2017-04-10 03:54:05 -07001975 CreateSenderCall(Call::Config(event_log_.get()));
perkj57c21f92016-06-17 07:27:16 -07001976
1977 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001978 CreateSendConfig(1, 0, 0, &transport);
perkj57c21f92016-06-17 07:27:16 -07001979
Sergey Ulanove2b15012016-11-22 16:08:30 -08001980 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
1981
perkj57c21f92016-06-17 07:27:16 -07001982 StartStopBitrateObserver encoder;
1983 video_send_config_.encoder_settings.encoder = &encoder;
1984 video_send_config_.encoder_settings.internal_source = true;
1985
1986 CreateVideoStreams();
1987
1988 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01001989
perkj57c21f92016-06-17 07:27:16 -07001990 video_send_stream_->Start();
Erik Språng08127a92016-11-16 16:41:30 +01001991 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
1992
perkj57c21f92016-06-17 07:27:16 -07001993 video_send_stream_->Stop();
Erik Språng08127a92016-11-16 16:41:30 +01001994 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
1995
perkj57c21f92016-06-17 07:27:16 -07001996 video_send_stream_->Start();
Erik Språng08127a92016-11-16 16:41:30 +01001997 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07001998
1999 DestroyStreams();
2000}
2001
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002002TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07002003 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002004 public:
Peter Boström5811a392015-12-10 13:02:50 +01002005 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002006
nissed30a1112016-04-18 05:15:22 -07002007 void OnFrame(const VideoFrame& video_frame) override {
2008 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01002009 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002010 }
2011
2012 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01002013 const int kWaitFrameTimeoutMs = 3000;
2014 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002015 << "Timeout while waiting for output frames.";
2016 }
2017
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002018 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002019 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002020 }
2021
2022 private:
2023 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002024 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002025
2026 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01002027 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002028 };
2029
2030 // Initialize send stream.
philipel4fb651d2017-04-10 03:54:05 -07002031 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002032
solenberg4fbae2b2015-08-28 04:07:10 -07002033 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08002034 CreateSendConfig(1, 0, 0, &transport);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002035 FrameObserver observer;
stefanff483612015-12-21 03:14:00 -08002036 video_send_config_.pre_encode_callback = &observer;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002037 CreateVideoStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002038
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002039 // Prepare five input frames. Send ordinary VideoFrame and texture frames
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002040 // alternatively.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002041 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07002042 int width = 168;
2043 int height = 132;
2044
Magnus Jedvert90e31902017-06-07 11:32:50 +02002045 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2046 width, height, 1, 1, kVideoRotation_0));
2047 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2048 width, height, 2, 2, kVideoRotation_0));
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002049 input_frames.push_back(CreateVideoFrame(width, height, 3));
2050 input_frames.push_back(CreateVideoFrame(width, height, 4));
Magnus Jedvert90e31902017-06-07 11:32:50 +02002051 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2052 width, height, 5, 5, kVideoRotation_0));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002053
stefanff483612015-12-21 03:14:00 -08002054 video_send_stream_->Start();
perkja49cbd32016-09-16 07:53:41 -07002055 test::FrameForwarder forwarder;
perkj803d97f2016-11-01 11:45:46 -07002056 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07002057 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002058 for (size_t i = 0; i < input_frames.size(); i++) {
perkja49cbd32016-09-16 07:53:41 -07002059 forwarder.IncomingCapturedFrame(input_frames[i]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002060 // Wait until the output frame is received before sending the next input
2061 // frame. Or the previous input frame may be replaced without delivering.
2062 observer.WaitOutputFrame();
2063 }
stefanff483612015-12-21 03:14:00 -08002064 video_send_stream_->Stop();
perkj803d97f2016-11-01 11:45:46 -07002065 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07002066 nullptr, VideoSendStream::DegradationPreference::kMaintainFramerate);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002067
2068 // Test if the input and output frames are the same. render_time_ms and
2069 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002070 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002071
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002072 DestroyStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002073}
2074
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002075void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
2076 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002077 EXPECT_EQ(frames1.size(), frames2.size());
2078 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07002079 // Compare frame buffers, since we don't care about differing timestamps.
2080 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
2081 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002082}
2083
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002084VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002085 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002086 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002087 memset(buffer.get(), data, kSizeY);
Magnus Jedvert90e31902017-06-07 11:32:50 +02002088 VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002089 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002090 // Use data as a ms timestamp.
2091 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002092 return frame;
2093}
2094
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002095TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
2096 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2097 public:
2098 EncoderStateObserver()
2099 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002100 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002101 initialized_(false),
2102 callback_registered_(false),
2103 num_releases_(0),
2104 released_(false) {}
2105
2106 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002107 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002108 return released_;
2109 }
2110
2111 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002112 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002113 return initialized_ && callback_registered_;
2114 }
2115
2116 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002117 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002118 return num_releases_;
2119 }
2120
2121 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002122 int32_t InitEncode(const VideoCodec* codecSettings,
2123 int32_t numberOfCores,
2124 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002125 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002126 EXPECT_FALSE(initialized_);
2127 initialized_ = true;
2128 released_ = false;
2129 return 0;
2130 }
2131
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002132 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002133 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002134 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002135 EXPECT_TRUE(IsReadyForEncode());
2136
Peter Boström5811a392015-12-10 13:02:50 +01002137 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002138 return 0;
2139 }
2140
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002141 int32_t RegisterEncodeCompleteCallback(
2142 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002143 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002144 EXPECT_TRUE(initialized_);
2145 callback_registered_ = true;
2146 return 0;
2147 }
2148
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002149 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002150 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002151 EXPECT_TRUE(IsReadyForEncode());
2152 EXPECT_FALSE(released_);
2153 initialized_ = false;
2154 callback_registered_ = false;
2155 released_ = true;
2156 ++num_releases_;
2157 return 0;
2158 }
2159
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002160 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002161 EXPECT_TRUE(IsReadyForEncode());
2162 return 0;
2163 }
2164
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002165 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002166 EXPECT_TRUE(IsReadyForEncode());
2167 return 0;
2168 }
2169
stefanff483612015-12-21 03:14:00 -08002170 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002171 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002172 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002173 stream_ = send_stream;
2174 }
2175
stefanff483612015-12-21 03:14:00 -08002176 void ModifyVideoConfigs(
2177 VideoSendStream::Config* send_config,
2178 std::vector<VideoReceiveStream::Config>* receive_configs,
2179 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002180 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07002181 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002182 }
2183
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002184 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002185 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
Per21d45d22016-10-30 21:37:57 +01002186 EXPECT_EQ(0u, num_releases());
perkj26091b12016-09-01 01:17:40 -07002187 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
Per21d45d22016-10-30 21:37:57 +01002188 EXPECT_EQ(0u, num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002189 stream_->Stop();
2190 // Encoder should not be released before destroying the VideoSendStream.
2191 EXPECT_FALSE(IsReleased());
2192 EXPECT_TRUE(IsReadyForEncode());
2193 stream_->Start();
2194 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002195 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002196 }
2197
Peter Boströmf2f82832015-05-01 13:00:41 +02002198 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002199 VideoSendStream* stream_;
2200 bool initialized_ GUARDED_BY(crit_);
2201 bool callback_registered_ GUARDED_BY(crit_);
2202 size_t num_releases_ GUARDED_BY(crit_);
2203 bool released_ GUARDED_BY(crit_);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002204 VideoEncoderConfig encoder_config_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002205 } test_encoder;
2206
stefane74eef12016-01-08 06:47:13 -08002207 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002208
2209 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002210 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002211}
2212
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002213TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2214 class VideoCodecConfigObserver : public test::SendTest,
2215 public test::FakeEncoder {
2216 public:
2217 VideoCodecConfigObserver()
2218 : SendTest(kDefaultTimeoutMs),
2219 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002220 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002221 num_initializations_(0),
2222 stream_(nullptr) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002223
2224 private:
stefanff483612015-12-21 03:14:00 -08002225 void ModifyVideoConfigs(
2226 VideoSendStream::Config* send_config,
2227 std::vector<VideoReceiveStream::Config>* receive_configs,
2228 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002229 send_config->encoder_settings.encoder = this;
sprangf24a0642017-02-28 13:23:26 -08002230 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002231 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002232 }
2233
stefanff483612015-12-21 03:14:00 -08002234 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002235 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002236 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002237 stream_ = send_stream;
2238 }
2239
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002240 int32_t InitEncode(const VideoCodec* config,
2241 int32_t number_of_cores,
2242 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002243 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002244 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002245 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002246 } else {
2247 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002248 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002249 }
2250 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002251 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002252 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2253 }
2254
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002255 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002256 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002257 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002258
sprangf24a0642017-02-28 13:23:26 -08002259 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002260 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002261 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002262 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002263 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2264 "new encoder settings.";
2265 }
2266
sprangf24a0642017-02-28 13:23:26 -08002267 const uint32_t kFirstMaxBitrateBps = 1000000;
2268 const uint32_t kSecondMaxBitrateBps = 2000000;
2269
pbos14fe7082016-04-20 06:35:56 -07002270 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002271 size_t num_initializations_;
2272 VideoSendStream* stream_;
2273 VideoEncoderConfig encoder_config_;
2274 } test;
2275
stefane74eef12016-01-08 06:47:13 -08002276 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002277}
2278
Peter Boström53eda3d2015-03-27 15:53:18 +01002279static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
2280template <typename T>
2281class VideoCodecConfigObserver : public test::SendTest,
2282 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002283 public:
2284 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2285 const char* codec_name)
2286 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2287 FakeEncoder(Clock::GetRealTimeClock()),
2288 video_codec_type_(video_codec_type),
2289 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002290 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002291 num_initializations_(0),
2292 stream_(nullptr) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002293 memset(&encoder_settings_, 0, sizeof(encoder_settings_));
2294 }
2295
2296 private:
perkjfa10b552016-10-02 23:45:26 -07002297 class VideoStreamFactory
2298 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2299 public:
2300 VideoStreamFactory() {}
2301
2302 private:
2303 std::vector<VideoStream> CreateEncoderStreams(
2304 int width,
2305 int height,
2306 const VideoEncoderConfig& encoder_config) override {
2307 std::vector<VideoStream> streams =
2308 test::CreateVideoStreams(width, height, encoder_config);
2309 for (size_t i = 0; i < streams.size(); ++i) {
2310 streams[i].temporal_layer_thresholds_bps.resize(
2311 kVideoCodecConfigObserverNumberOfTemporalLayers - 1);
2312 }
2313 return streams;
2314 }
2315 };
2316
stefanff483612015-12-21 03:14:00 -08002317 void ModifyVideoConfigs(
2318 VideoSendStream::Config* send_config,
2319 std::vector<VideoReceiveStream::Config>* receive_configs,
2320 VideoEncoderConfig* encoder_config) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002321 send_config->encoder_settings.encoder = this;
2322 send_config->encoder_settings.payload_name = codec_name_;
2323
kthelgason29a44e32016-09-27 03:52:02 -07002324 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002325 encoder_config->video_stream_factory =
2326 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002327 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002328 }
2329
stefanff483612015-12-21 03:14:00 -08002330 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002331 VideoSendStream* send_stream,
2332 const std::vector<VideoReceiveStream*>& receive_streams) override {
2333 stream_ = send_stream;
2334 }
2335
2336 int32_t InitEncode(const VideoCodec* config,
2337 int32_t number_of_cores,
2338 size_t max_payload_size) override {
2339 EXPECT_EQ(video_codec_type_, config->codecType);
2340 VerifyCodecSpecifics(*config);
2341 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002342 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002343 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2344 }
2345
2346 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002347 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2348 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002349
2350 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002351 EXPECT_TRUE(
2352 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002353 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002354
2355 encoder_settings_.frameDroppingOn = true;
kthelgason29a44e32016-09-27 03:52:02 -07002356 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002357 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002358 ASSERT_TRUE(
2359 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002360 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002361 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2362 "new encoder settings.";
2363 }
2364
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002365 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002366 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002367 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002368 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2369 return 0;
2370 }
2371
2372 T encoder_settings_;
2373 const VideoCodecType video_codec_type_;
2374 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002375 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002376 size_t num_initializations_;
2377 VideoSendStream* stream_;
2378 VideoEncoderConfig encoder_config_;
2379};
2380
2381template <>
2382void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2383 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002384 EXPECT_EQ(
2385 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002386}
kthelgason29a44e32016-09-27 03:52:02 -07002387
2388template <>
2389rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2390VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2391 return new rtc::RefCountedObject<
2392 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2393}
2394
Peter Boström53eda3d2015-03-27 15:53:18 +01002395template <>
2396void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2397 const VideoCodec& config) const {
2398 // Check that the number of temporal layers has propagated properly to
2399 // VideoCodec.
2400 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002401 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002402
2403 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2404 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2405 config.simulcastStream[i].numberOfTemporalLayers);
2406 }
2407
2408 // Set expected temporal layers as they should have been set when
Erik Språng08127a92016-11-16 16:41:30 +01002409 // reconfiguring the encoder and not match the set config. Also copy the
2410 // TemporalLayersFactory pointer that has been injected by ViEEncoder.
Peter Boström53eda3d2015-03-27 15:53:18 +01002411 VideoCodecVP8 encoder_settings = encoder_settings_;
2412 encoder_settings.numberOfTemporalLayers =
2413 kVideoCodecConfigObserverNumberOfTemporalLayers;
Erik Språng08127a92016-11-16 16:41:30 +01002414 encoder_settings.tl_factory = config.VP8().tl_factory;
hta257dc392016-10-25 09:05:06 -07002415 EXPECT_EQ(
2416 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002417}
kthelgason29a44e32016-09-27 03:52:02 -07002418
2419template <>
2420rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2421VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2422 return new rtc::RefCountedObject<
2423 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2424}
2425
Peter Boström53eda3d2015-03-27 15:53:18 +01002426template <>
2427void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2428 const VideoCodec& config) const {
2429 // Check that the number of temporal layers has propagated properly to
2430 // VideoCodec.
2431 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002432 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002433
2434 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2435 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2436 config.simulcastStream[i].numberOfTemporalLayers);
2437 }
2438
2439 // Set expected temporal layers as they should have been set when
2440 // reconfiguring the encoder and not match the set config.
2441 VideoCodecVP9 encoder_settings = encoder_settings_;
2442 encoder_settings.numberOfTemporalLayers =
2443 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002444 EXPECT_EQ(
2445 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002446}
2447
kthelgason29a44e32016-09-27 03:52:02 -07002448template <>
2449rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2450VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2451 return new rtc::RefCountedObject<
2452 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2453}
2454
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002455TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002456 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002457 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002458}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002459
Peter Boström53eda3d2015-03-27 15:53:18 +01002460TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2461 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002462 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002463}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002464
Peter Boström53eda3d2015-03-27 15:53:18 +01002465TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2466 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002467 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002468}
2469
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002470TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002471 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002472 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002473 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2474 rtp_packets_sent_(0),
2475 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002476
2477 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002478 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002479 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002480 RTPHeader header;
2481 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002482 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002483 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2484 return SEND_PACKET;
2485 }
2486
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002487 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002488 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002489 test::RtcpPacketParser parser;
2490 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002491
danilchap3dc929e2016-11-02 08:21:59 -07002492 if (parser.sender_report()->num_packets() > 0) {
2493 // Only compare sent media bytes if SenderPacketCount matches the
2494 // number of sent rtp packets (a new rtp packet could be sent before
2495 // the rtcp packet).
2496 if (parser.sender_report()->sender_octet_count() > 0 &&
2497 parser.sender_report()->sender_packet_count() ==
2498 rtp_packets_sent_) {
2499 EXPECT_EQ(media_bytes_sent_,
2500 parser.sender_report()->sender_octet_count());
2501 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002502 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002503 }
2504
2505 return SEND_PACKET;
2506 }
2507
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002508 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002509 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002510 }
2511
stefan4b569042015-11-11 06:39:57 -08002512 rtc::CriticalSection crit_;
2513 size_t rtp_packets_sent_ GUARDED_BY(&crit_);
2514 size_t media_bytes_sent_ GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002515 } test;
2516
stefane74eef12016-01-08 06:47:13 -08002517 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002518}
2519
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002520TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
2521 static const int kScreencastTargetBitrateKbps = 200;
perkjfa10b552016-10-02 23:45:26 -07002522
2523 class VideoStreamFactory
2524 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2525 public:
2526 VideoStreamFactory() {}
2527
2528 private:
2529 std::vector<VideoStream> CreateEncoderStreams(
2530 int width,
2531 int height,
2532 const VideoEncoderConfig& encoder_config) override {
2533 std::vector<VideoStream> streams =
2534 test::CreateVideoStreams(width, height, encoder_config);
2535 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
2536 streams[0].temporal_layer_thresholds_bps.push_back(
2537 kScreencastTargetBitrateKbps * 1000);
2538 return streams;
2539 }
2540 };
2541
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002542 class ScreencastTargetBitrateTest : public test::SendTest,
2543 public test::FakeEncoder {
2544 public:
2545 ScreencastTargetBitrateTest()
2546 : SendTest(kDefaultTimeoutMs),
2547 test::FakeEncoder(Clock::GetRealTimeClock()) {}
2548
2549 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002550 int32_t InitEncode(const VideoCodec* config,
2551 int32_t number_of_cores,
2552 size_t max_payload_size) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002553 EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps),
2554 config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002555 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002556 return test::FakeEncoder::InitEncode(
2557 config, number_of_cores, max_payload_size);
2558 }
stefanff483612015-12-21 03:14:00 -08002559 void ModifyVideoConfigs(
2560 VideoSendStream::Config* send_config,
2561 std::vector<VideoReceiveStream::Config>* receive_configs,
2562 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002563 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002564 EXPECT_EQ(1u, encoder_config->number_of_streams);
2565 encoder_config->video_stream_factory =
2566 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002567 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002568 }
2569
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002570 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002571 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002572 << "Timed out while waiting for the encoder to be initialized.";
2573 }
2574 } test;
2575
stefane74eef12016-01-08 06:47:13 -08002576 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002577}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002578
philipelc6957c72016-04-28 15:52:49 +02002579TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002580 // These are chosen to be "kind of odd" to not be accidentally checked against
2581 // default values.
2582 static const int kMinBitrateKbps = 137;
2583 static const int kStartBitrateKbps = 345;
2584 static const int kLowerMaxBitrateKbps = 312;
2585 static const int kMaxBitrateKbps = 413;
2586 static const int kIncreasedStartBitrateKbps = 451;
2587 static const int kIncreasedMaxBitrateKbps = 597;
2588 class EncoderBitrateThresholdObserver : public test::SendTest,
2589 public test::FakeEncoder {
2590 public:
2591 EncoderBitrateThresholdObserver()
2592 : SendTest(kDefaultTimeoutMs),
2593 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002594 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002595 bitrate_changed_event_(false, false),
2596 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002597 num_initializations_(0),
2598 call_(nullptr),
2599 send_stream_(nullptr) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002600
2601 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002602 int32_t InitEncode(const VideoCodec* codecSettings,
2603 int32_t numberOfCores,
2604 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002605 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2606 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002607 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002608 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2609 codecSettings->minBitrate);
2610 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2611 codecSettings->startBitrate);
2612 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2613 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002614 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002615 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002616 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2617 codecSettings->maxBitrate);
2618 // The start bitrate should be kept (-1) and capped to the max bitrate.
2619 // Since this is not an end-to-end call no receiver should have been
2620 // returning a REMB that could lower this estimate.
2621 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002622 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002623 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2624 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002625 // The start bitrate will be whatever the rate BitRateController
2626 // has currently configured but in the span of the set max and min
2627 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002628 }
2629 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002630 init_encode_event_.Set();
2631
pbos@webrtc.org00873182014-11-25 14:03:34 +00002632 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2633 maxPayloadSize);
2634 }
2635
Erik Språng08127a92016-11-16 16:41:30 +01002636 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
2637 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002638 {
2639 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002640 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2641 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002642 }
Erik Språng08127a92016-11-16 16:41:30 +01002643 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002644 }
2645 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002646 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002647 }
2648
2649 void WaitForSetRates(uint32_t expected_bitrate) {
2650 EXPECT_TRUE(
2651 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2652 << "Timed out while waiting encoder rate to be set.";
2653 rtc::CritScope lock(&crit_);
2654 EXPECT_EQ(expected_bitrate, target_bitrate_);
2655 }
2656
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002657 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07002658 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01002659 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2660 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2661 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002662 return config;
2663 }
2664
perkjfa10b552016-10-02 23:45:26 -07002665 class VideoStreamFactory
2666 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2667 public:
2668 explicit VideoStreamFactory(int min_bitrate_bps)
2669 : min_bitrate_bps_(min_bitrate_bps) {}
2670
2671 private:
2672 std::vector<VideoStream> CreateEncoderStreams(
2673 int width,
2674 int height,
2675 const VideoEncoderConfig& encoder_config) override {
2676 std::vector<VideoStream> streams =
2677 test::CreateVideoStreams(width, height, encoder_config);
2678 streams[0].min_bitrate_bps = min_bitrate_bps_;
2679 return streams;
2680 }
2681
2682 const int min_bitrate_bps_;
2683 };
2684
stefanff483612015-12-21 03:14:00 -08002685 void ModifyVideoConfigs(
2686 VideoSendStream::Config* send_config,
2687 std::vector<VideoReceiveStream::Config>* receive_configs,
2688 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002689 send_config->encoder_settings.encoder = this;
2690 // Set bitrates lower/higher than min/max to make sure they are properly
2691 // capped.
perkjfa10b552016-10-02 23:45:26 -07002692 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2693 // Create a new StreamFactory to be able to set
2694 // |VideoStream.min_bitrate_bps|.
2695 encoder_config->video_stream_factory =
2696 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002697 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002698 }
2699
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002700 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002701 call_ = sender_call;
2702 }
2703
stefanff483612015-12-21 03:14:00 -08002704 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002705 VideoSendStream* send_stream,
2706 const std::vector<VideoReceiveStream*>& receive_streams) override {
2707 send_stream_ = send_stream;
2708 }
2709
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002710 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002711 ASSERT_TRUE(
2712 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002713 << "Timed out while waiting for encoder to be configured.";
2714 WaitForSetRates(kStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002715 Call::Config::BitrateConfig bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002716 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2717 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2718 call_->SetBitrateConfig(bitrate_config);
perkj26091b12016-09-01 01:17:40 -07002719 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2720 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002721 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002722 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002723 ASSERT_TRUE(
2724 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002725 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002726 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002727 WaitForSetRates(kLowerMaxBitrateKbps);
2728
2729 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2730 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2731 ASSERT_TRUE(
2732 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002733 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002734 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002735 // Expected target bitrate is the start bitrate set in the call to
2736 // call_->SetBitrateConfig.
2737 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002738 }
2739
pbos14fe7082016-04-20 06:35:56 -07002740 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002741 rtc::Event bitrate_changed_event_;
2742 rtc::CriticalSection crit_;
2743 uint32_t target_bitrate_ GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002744
pbos@webrtc.org00873182014-11-25 14:03:34 +00002745 int num_initializations_;
2746 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002747 webrtc::VideoSendStream* send_stream_;
2748 webrtc::VideoEncoderConfig encoder_config_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002749 } test;
2750
stefane74eef12016-01-08 06:47:13 -08002751 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002752}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002753
2754TEST_F(VideoSendStreamTest, ReportsSentResolution) {
2755 static const size_t kNumStreams = 3;
2756 // Unusual resolutions to make sure that they are the ones being reported.
2757 static const struct {
2758 int width;
2759 int height;
2760 } kEncodedResolution[kNumStreams] = {
2761 {241, 181}, {300, 121}, {121, 221}};
2762 class ScreencastTargetBitrateTest : public test::SendTest,
2763 public test::FakeEncoder {
2764 public:
2765 ScreencastTargetBitrateTest()
2766 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002767 test::FakeEncoder(Clock::GetRealTimeClock()),
2768 send_stream_(nullptr) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002769
2770 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002771 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002772 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002773 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002774 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002775 specifics.codecType = kVideoCodecGeneric;
2776
2777 uint8_t buffer[16] = {0};
2778 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
2779 encoded._timeStamp = input_image.timestamp();
2780 encoded.capture_time_ms_ = input_image.render_time_ms();
2781
2782 for (size_t i = 0; i < kNumStreams; ++i) {
2783 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
2784 encoded._frameType = (*frame_types)[i];
2785 encoded._encodedWidth = kEncodedResolution[i].width;
2786 encoded._encodedHeight = kEncodedResolution[i].height;
brandtre78d2662017-01-16 05:57:16 -08002787 EncodedImageCallback* callback;
2788 {
2789 rtc::CritScope cs(&crit_sect_);
2790 callback = callback_;
2791 }
2792 RTC_DCHECK(callback);
2793 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07002794 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002795 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07002796 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002797 }
2798
Peter Boström5811a392015-12-10 13:02:50 +01002799 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002800 return 0;
2801 }
stefanff483612015-12-21 03:14:00 -08002802 void ModifyVideoConfigs(
2803 VideoSendStream::Config* send_config,
2804 std::vector<VideoReceiveStream::Config>* receive_configs,
2805 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002806 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002807 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002808 }
2809
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002810 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002811
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002812 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002813 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002814 << "Timed out while waiting for the encoder to send one frame.";
2815 VideoSendStream::Stats stats = send_stream_->GetStats();
2816
2817 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002818 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002819 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002820 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002821 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002822 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002823 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002824 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
2825 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002826 }
2827 }
2828
stefanff483612015-12-21 03:14:00 -08002829 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002830 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002831 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002832 send_stream_ = send_stream;
2833 }
2834
2835 VideoSendStream* send_stream_;
2836 } test;
2837
stefane74eef12016-01-08 06:47:13 -08002838 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002839}
philipel0f9af012015-09-01 07:01:51 -07002840
Peter Boström12996152016-05-14 02:03:18 +02002841#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01002842class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07002843 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01002844 Vp9HeaderObserver()
2845 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
philipel7fabd462015-09-03 04:42:32 -07002846 vp9_encoder_(VP9Encoder::Create()),
Åsa Perssonff24c042015-12-04 10:58:08 +01002847 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
2848 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07002849 frames_sent_(0),
2850 expected_width_(0),
2851 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07002852
stefanff483612015-12-21 03:14:00 -08002853 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07002854 VideoSendStream::Config* send_config,
2855 std::vector<VideoReceiveStream::Config>* receive_configs,
2856 VideoEncoderConfig* encoder_config) {}
2857
Åsa Perssonff24c042015-12-04 10:58:08 +01002858 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07002859
2860 private:
minyue20c84cc2017-04-10 16:57:57 -07002861 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07002862
perkjfa10b552016-10-02 23:45:26 -07002863 class VideoStreamFactory
2864 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2865 public:
2866 explicit VideoStreamFactory(size_t number_of_temporal_layers)
2867 : number_of_temporal_layers_(number_of_temporal_layers) {}
2868
2869 private:
2870 std::vector<VideoStream> CreateEncoderStreams(
2871 int width,
2872 int height,
2873 const VideoEncoderConfig& encoder_config) override {
2874 std::vector<VideoStream> streams =
2875 test::CreateVideoStreams(width, height, encoder_config);
2876 streams[0].temporal_layer_thresholds_bps.resize(
2877 number_of_temporal_layers_ - 1);
2878 return streams;
2879 }
2880
2881 const size_t number_of_temporal_layers_;
2882 };
2883
stefanff483612015-12-21 03:14:00 -08002884 void ModifyVideoConfigs(
2885 VideoSendStream::Config* send_config,
2886 std::vector<VideoReceiveStream::Config>* receive_configs,
2887 VideoEncoderConfig* encoder_config) override {
philipel7fabd462015-09-03 04:42:32 -07002888 send_config->encoder_settings.encoder = vp9_encoder_.get();
philipel0f9af012015-09-01 07:01:51 -07002889 send_config->encoder_settings.payload_name = "VP9";
2890 send_config->encoder_settings.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08002891 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07002892 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
2893 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07002894 EXPECT_EQ(1u, encoder_config->number_of_streams);
2895 encoder_config->video_stream_factory =
2896 new rtc::RefCountedObject<VideoStreamFactory>(
2897 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07002898 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07002899 }
2900
perkjfa10b552016-10-02 23:45:26 -07002901 void ModifyVideoCaptureStartResolution(int* width,
2902 int* height,
2903 int* frame_rate) override {
2904 expected_width_ = *width;
2905 expected_height_ = *height;
2906 }
2907
philipel0f9af012015-09-01 07:01:51 -07002908 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002909 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
2910 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002911 }
2912
2913 Action OnSendRtp(const uint8_t* packet, size_t length) override {
2914 RTPHeader header;
2915 EXPECT_TRUE(parser_->Parse(packet, length, &header));
2916
Åsa Perssonff24c042015-12-04 10:58:08 +01002917 EXPECT_EQ(kVp9PayloadType, header.payloadType);
2918 const uint8_t* payload = packet + header.headerLength;
2919 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07002920
Åsa Perssonff24c042015-12-04 10:58:08 +01002921 bool new_packet = packets_sent_ == 0 ||
2922 IsNewerSequenceNumber(header.sequenceNumber,
2923 last_header_.sequenceNumber);
2924 if (payload_length > 0 && new_packet) {
2925 RtpDepacketizer::ParsedPayload parsed;
2926 RtpDepacketizerVp9 depacketizer;
2927 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
2928 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
2929 // Verify common fields for all configurations.
2930 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
2931 CompareConsecutiveFrames(header, parsed.type.Video);
2932 // Verify configuration specific settings.
2933 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07002934
Åsa Perssonff24c042015-12-04 10:58:08 +01002935 ++packets_sent_;
2936 if (header.markerBit) {
2937 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002938 }
Åsa Perssonff24c042015-12-04 10:58:08 +01002939 last_header_ = header;
2940 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07002941 }
philipel0f9af012015-09-01 07:01:51 -07002942 return SEND_PACKET;
2943 }
2944
philipel7fabd462015-09-03 04:42:32 -07002945 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01002946 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
2947 if (last_vp9_.picture_id > vp9.picture_id) {
2948 return vp9.picture_id == 0; // Wrap.
2949 } else {
2950 return vp9.picture_id == last_vp9_.picture_id + 1;
2951 }
2952 }
2953
2954 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01002955 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
2956 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
2957 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
2958 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
2959 vp9.spatial_idx);
2960 }
2961
2962 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
2963 uint8_t num_layers) const {
2964 switch (num_layers) {
2965 case 0:
2966 VerifyTemporalLayerStructure0(vp9);
2967 break;
2968 case 1:
2969 VerifyTemporalLayerStructure1(vp9);
2970 break;
2971 case 2:
2972 VerifyTemporalLayerStructure2(vp9);
2973 break;
2974 case 3:
2975 VerifyTemporalLayerStructure3(vp9);
2976 break;
2977 default:
2978 RTC_NOTREACHED();
2979 }
2980 }
2981
2982 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
2983 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
2984 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
2985 EXPECT_FALSE(vp9.temporal_up_switch);
2986 }
2987
2988 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
2989 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2990 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
2991 EXPECT_FALSE(vp9.temporal_up_switch);
2992 }
2993
2994 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
2995 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2996 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
2997 EXPECT_LE(vp9.temporal_idx, 1);
2998 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
2999 if (IsNewPictureId(vp9)) {
3000 uint8_t expected_tid =
3001 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3002 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3003 }
3004 }
3005
3006 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3007 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3008 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3009 EXPECT_LE(vp9.temporal_idx, 2);
3010 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3011 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3012 switch (vp9.temporal_idx) {
3013 case 0:
3014 EXPECT_EQ(2, last_vp9_.temporal_idx);
3015 EXPECT_FALSE(vp9.temporal_up_switch);
3016 break;
3017 case 1:
3018 EXPECT_EQ(2, last_vp9_.temporal_idx);
3019 EXPECT_TRUE(vp9.temporal_up_switch);
3020 break;
3021 case 2:
3022 EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
3023 break;
3024 }
3025 }
3026 }
3027
3028 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3029 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3030 return;
3031
3032 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3033 if (vp9.temporal_idx == 0)
3034 ++expected_tl0_idx;
3035 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3036 }
3037
3038 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3039 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3040 }
3041
3042 // Flexible mode (F=1): Non-flexible mode (F=0):
3043 //
3044 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3045 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3046 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3047 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3048 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3049 // M: | EXTENDED PID | M: | EXTENDED PID |
3050 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3051 // L: | T |U| S |D| L: | T |U| S |D|
3052 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3053 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3054 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3055 // X: |EXTENDED P_DIFF| V: | SS .. |
3056 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3057 // V: | SS .. |
3058 // +-+-+-+-+-+-+-+-+
3059 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3060 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3061 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3062 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
3063 EXPECT_GE(vp9.spatial_idx, 0); // S
3064 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3065 if (vp9.ss_data_available) // V
3066 VerifySsData(vp9);
3067
3068 if (frames_sent_ == 0)
3069 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3070
3071 if (!vp9.inter_pic_predicted) {
3072 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3073 EXPECT_FALSE(vp9.temporal_up_switch);
3074 }
3075 }
3076
3077 // Scalability structure (SS).
3078 //
3079 // +-+-+-+-+-+-+-+-+
3080 // V: | N_S |Y|G|-|-|-|
3081 // +-+-+-+-+-+-+-+-+
3082 // Y: | WIDTH | N_S + 1 times
3083 // +-+-+-+-+-+-+-+-+
3084 // | HEIGHT |
3085 // +-+-+-+-+-+-+-+-+
3086 // G: | N_G |
3087 // +-+-+-+-+-+-+-+-+
3088 // N_G: | T |U| R |-|-| N_G times
3089 // +-+-+-+-+-+-+-+-+
3090 // | P_DIFF | R times
3091 // +-+-+-+-+-+-+-+-+
3092 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3093 EXPECT_TRUE(vp9.ss_data_available); // V
3094 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3095 vp9.num_spatial_layers);
3096 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003097 int expected_width = expected_width_;
3098 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003099 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003100 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3101 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3102 expected_width /= 2;
3103 expected_height /= 2;
3104 }
3105 }
3106
3107 void CompareConsecutiveFrames(const RTPHeader& header,
3108 const RTPVideoHeader& video) const {
3109 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
3110
3111 bool new_frame = packets_sent_ == 0 ||
3112 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003113 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003114 if (!new_frame) {
3115 EXPECT_FALSE(last_header_.markerBit);
3116 EXPECT_EQ(last_header_.timestamp, header.timestamp);
3117 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
3118 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
3119 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
3120 VerifySpatialIdxWithinFrame(vp9);
3121 return;
3122 }
3123 // New frame.
3124 EXPECT_TRUE(vp9.beginning_of_frame);
3125
3126 // Compare with last packet in previous frame.
3127 if (frames_sent_ == 0)
3128 return;
3129 EXPECT_TRUE(last_vp9_.end_of_frame);
3130 EXPECT_TRUE(last_header_.markerBit);
3131 EXPECT_TRUE(ContinuousPictureId(vp9));
3132 VerifyTl0Idx(vp9);
3133 }
3134
kwiberg27f982b2016-03-01 11:52:33 -08003135 std::unique_ptr<VP9Encoder> vp9_encoder_;
philipel0f9af012015-09-01 07:01:51 -07003136 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003137 webrtc::VideoEncoderConfig encoder_config_;
3138 RTPHeader last_header_;
3139 RTPVideoHeaderVP9 last_vp9_;
3140 size_t packets_sent_;
3141 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003142 int expected_width_;
3143 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003144};
3145
Åsa Perssonff24c042015-12-04 10:58:08 +01003146TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
3147 const uint8_t kNumTemporalLayers = 1;
3148 const uint8_t kNumSpatialLayers = 1;
3149 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3150}
3151
3152TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
3153 const uint8_t kNumTemporalLayers = 2;
3154 const uint8_t kNumSpatialLayers = 1;
3155 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3156}
3157
3158TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
3159 const uint8_t kNumTemporalLayers = 3;
3160 const uint8_t kNumSpatialLayers = 1;
3161 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3162}
3163
3164TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
3165 const uint8_t kNumTemporalLayers = 1;
3166 const uint8_t kNumSpatialLayers = 2;
3167 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3168}
3169
3170TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3171 const uint8_t kNumTemporalLayers = 2;
3172 const uint8_t kNumSpatialLayers = 2;
3173 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3174}
3175
3176TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3177 const uint8_t kNumTemporalLayers = 3;
3178 const uint8_t kNumSpatialLayers = 2;
3179 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3180}
3181
3182void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3183 uint8_t num_spatial_layers) {
3184 static const size_t kNumFramesToSend = 100;
3185 // Set to < kNumFramesToSend and coprime to length of temporal layer
3186 // structures to verify temporal id reset on key frame.
3187 static const int kKeyFrameInterval = 31;
3188 class NonFlexibleMode : public Vp9HeaderObserver {
3189 public:
3190 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3191 : num_temporal_layers_(num_temporal_layers),
3192 num_spatial_layers_(num_spatial_layers),
3193 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
stefanff483612015-12-21 03:14:00 -08003194 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003195 VideoSendStream::Config* send_config,
3196 std::vector<VideoReceiveStream::Config>* receive_configs,
3197 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003198 vp9_settings_.flexibleMode = false;
3199 vp9_settings_.frameDroppingOn = false;
3200 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3201 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3202 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003203 }
3204
Åsa Perssonff24c042015-12-04 10:58:08 +01003205 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
3206 bool ss_data_expected = !vp9.inter_pic_predicted &&
3207 vp9.beginning_of_frame && vp9.spatial_idx == 0;
3208 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
3209 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted); // D
asapersson38bb8ad2015-12-14 01:41:19 -08003210 EXPECT_EQ(!vp9.inter_pic_predicted,
3211 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003212
3213 if (IsNewPictureId(vp9)) {
3214 EXPECT_EQ(0, vp9.spatial_idx);
3215 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
3216 }
3217
3218 VerifyFixedTemporalLayerStructure(vp9,
3219 l_field_ ? num_temporal_layers_ : 0);
3220
3221 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003222 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003223 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003224 const uint8_t num_temporal_layers_;
3225 const uint8_t num_spatial_layers_;
3226 const bool l_field_;
3227 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003228
stefane74eef12016-01-08 06:47:13 -08003229 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003230}
3231
asaperssond9f641e2016-01-21 01:11:35 -08003232TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3233 static const size_t kNumFramesToSend = 50;
3234 static const int kWidth = 4;
3235 static const int kHeight = 4;
3236 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3237 void ModifyVideoConfigsHook(
3238 VideoSendStream::Config* send_config,
3239 std::vector<VideoReceiveStream::Config>* receive_configs,
3240 VideoEncoderConfig* encoder_config) override {
3241 vp9_settings_.flexibleMode = false;
3242 vp9_settings_.numberOfTemporalLayers = 1;
3243 vp9_settings_.numberOfSpatialLayers = 1;
3244
perkjfa10b552016-10-02 23:45:26 -07003245 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003246 }
3247
3248 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3249 if (frames_sent_ > kNumFramesToSend)
3250 observation_complete_.Set();
3251 }
perkjfa10b552016-10-02 23:45:26 -07003252
3253 void ModifyVideoCaptureStartResolution(int* width,
3254 int* height,
3255 int* frame_rate) override {
3256 expected_width_ = kWidth;
3257 expected_height_ = kHeight;
3258 *width = kWidth;
3259 *height = kHeight;
3260 }
asaperssond9f641e2016-01-21 01:11:35 -08003261 } test;
3262
3263 RunBaseTest(&test);
3264}
3265
kjellanderf9e2a362017-03-24 12:17:33 -07003266#if defined(WEBRTC_ANDROID)
3267// Crashes on Android; bugs.webrtc.org/7401
3268#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3269#else
3270#define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
3271#endif
3272TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003273 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003274 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003275 VideoSendStream::Config* send_config,
3276 std::vector<VideoReceiveStream::Config>* receive_configs,
3277 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003278 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003279 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003280 vp9_settings_.numberOfTemporalLayers = 1;
3281 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003282 }
3283
Åsa Perssonff24c042015-12-04 10:58:08 +01003284 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3285 EXPECT_TRUE(vp9_header.flexible_mode);
3286 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3287 if (vp9_header.inter_pic_predicted) {
3288 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003289 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003290 }
3291 }
3292 } test;
3293
stefane74eef12016-01-08 06:47:13 -08003294 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003295}
Peter Boström12996152016-05-14 02:03:18 +02003296#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003297
perkj803d97f2016-11-01 11:45:46 -07003298void VideoSendStreamTest::TestRequestSourceRotateVideo(
3299 bool support_orientation_ext) {
philipel4fb651d2017-04-10 03:54:05 -07003300 CreateSenderCall(Call::Config(event_log_.get()));
perkj803d97f2016-11-01 11:45:46 -07003301
3302 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003303 CreateSendConfig(1, 0, 0, &transport);
perkj803d97f2016-11-01 11:45:46 -07003304 video_send_config_.rtp.extensions.clear();
3305 if (support_orientation_ext) {
3306 video_send_config_.rtp.extensions.push_back(
3307 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3308 }
3309
3310 CreateVideoStreams();
3311 test::FrameForwarder forwarder;
3312 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07003313 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
perkj803d97f2016-11-01 11:45:46 -07003314
3315 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3316 support_orientation_ext);
3317
3318 DestroyStreams();
3319}
3320
3321TEST_F(VideoSendStreamTest,
3322 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3323 TestRequestSourceRotateVideo(false);
3324}
3325
3326TEST_F(VideoSendStreamTest,
3327 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3328 TestRequestSourceRotateVideo(true);
3329}
3330
michaelta3328772016-11-29 09:25:03 -08003331// This test verifies that overhead is removed from the bandwidth estimate by
3332// testing that the maximum possible target payload rate is smaller than the
3333// maximum bandwidth estimate by the overhead rate.
michaelt273f31b2017-02-08 08:21:52 -08003334TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003335 test::ScopedFieldTrials override_field_trials(
3336 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3337 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3338 public test::FakeEncoder {
3339 public:
3340 RemoveOverheadFromBandwidthTest()
3341 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3342 FakeEncoder(Clock::GetRealTimeClock()),
3343 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003344 max_bitrate_bps_(0),
3345 first_packet_sent_(false),
3346 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003347
3348 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
3349 uint32_t frameRate) override {
3350 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003351 // Wait for the first sent packet so that videosendstream knows
3352 // rtp_overhead.
3353 if (first_packet_sent_) {
3354 max_bitrate_bps_ = bitrate.get_sum_bps();
3355 bitrate_changed_event_.Set();
3356 }
michaelta3328772016-11-29 09:25:03 -08003357 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3358 }
3359
3360 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3361 call_ = sender_call;
3362 }
3363
3364 void ModifyVideoConfigs(
3365 VideoSendStream::Config* send_config,
3366 std::vector<VideoReceiveStream::Config>* receive_configs,
3367 VideoEncoderConfig* encoder_config) override {
3368 send_config->rtp.max_packet_size = 1200;
3369 send_config->encoder_settings.encoder = this;
3370 EXPECT_FALSE(send_config->rtp.extensions.empty());
3371 }
3372
michaelt192132e2017-01-26 09:05:27 -08003373 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3374 rtc::CritScope lock(&crit_);
3375 first_packet_sent_ = true;
3376 return SEND_PACKET;
3377 }
3378
michaelta3328772016-11-29 09:25:03 -08003379 void PerformTest() override {
michaelta3328772016-11-29 09:25:03 -08003380 Call::Config::BitrateConfig bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003381 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003382 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003383 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003384 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3385 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003386 bitrate_config.min_bitrate_bps = kMinBitrateBps;
michaelta3328772016-11-29 09:25:03 -08003387 call_->SetBitrateConfig(bitrate_config);
michaelt273f31b2017-02-08 08:21:52 -08003388 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
michaelta3328772016-11-29 09:25:03 -08003389
3390 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003391 // overhead of 40B per packet video produces 2240bps overhead.
3392 // So the encoder BW should be set to 57760bps.
3393 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
michaelta3328772016-11-29 09:25:03 -08003394 {
3395 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003396 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003397 }
3398 }
3399
3400 private:
3401 Call* call_;
3402 rtc::CriticalSection crit_;
michaelt192132e2017-01-26 09:05:27 -08003403 uint32_t max_bitrate_bps_ GUARDED_BY(&crit_);
3404 bool first_packet_sent_ GUARDED_BY(&crit_);
3405 rtc::Event bitrate_changed_event_;
michaelta3328772016-11-29 09:25:03 -08003406 } test;
3407
3408 RunBaseTest(&test);
3409}
3410
sprang168794c2017-07-06 04:38:06 -07003411TEST_F(VideoSendStreamTest, SendsKeepAlive) {
3412 const int kTimeoutMs = 50; // Really short timeout for testing.
sprang168794c2017-07-06 04:38:06 -07003413
3414 class KeepaliveObserver : public test::SendTest {
3415 public:
3416 KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
3417
sprange5c4a812017-07-11 03:44:17 -07003418 Call::Config GetSenderCallConfig() override {
3419 Call::Config config = SendTest::GetSenderCallConfig();
3420 config.keepalive_config.timeout_interval_ms = kTimeoutMs;
3421 config.keepalive_config.payload_type =
3422 CallTest::kDefaultKeepalivePayloadType;
3423 return config;
3424 }
3425
sprang168794c2017-07-06 04:38:06 -07003426 private:
3427 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3428 RTPHeader header;
3429 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3430
sprangd2702ef2017-07-10 08:41:10 -07003431 if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
sprang168794c2017-07-06 04:38:06 -07003432 // The video stream has started. Stop it now.
3433 if (capturer_)
3434 capturer_->Stop();
3435 } else {
3436 observation_complete_.Set();
3437 }
3438
3439 return SEND_PACKET;
3440 }
3441
sprang168794c2017-07-06 04:38:06 -07003442 void PerformTest() override {
3443 EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
3444 }
3445
3446 void OnFrameGeneratorCapturerCreated(
3447 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3448 capturer_ = frame_generator_capturer;
3449 }
3450
3451 test::FrameGeneratorCapturer* capturer_ = nullptr;
3452 } test;
3453
3454 RunBaseTest(&test);
3455}
3456
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003457} // namespace webrtc