blob: 93df93fda4daa294877a6128d799a944e2519566 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "call/call.h"
15#include "call/rtp_transport_controller_send.h"
16#include "common_video/include/frame_callback.h"
17#include "common_video/include/video_frame.h"
Erik Språng7c8cca32017-10-24 17:05:18 +020018#include "modules/pacing/alr_detector.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "modules/rtp_rtcp/include/rtp_header_parser.h"
20#include "modules/rtp_rtcp/include/rtp_rtcp.h"
21#include "modules/rtp_rtcp/source/rtcp_sender.h"
22#include "modules/rtp_rtcp/source/rtp_format_vp9.h"
23#include "modules/video_coding/codecs/vp8/include/vp8.h"
24#include "modules/video_coding/codecs/vp9/include/vp9.h"
25#include "rtc_base/bind.h"
26#include "rtc_base/checks.h"
27#include "rtc_base/criticalsection.h"
28#include "rtc_base/event.h"
29#include "rtc_base/logging.h"
30#include "rtc_base/platform_thread.h"
31#include "rtc_base/rate_limiter.h"
32#include "rtc_base/timeutils.h"
33#include "system_wrappers/include/sleep.h"
34#include "test/call_test.h"
35#include "test/configurable_frame_size_encoder.h"
36#include "test/fake_texture_frame.h"
37#include "test/field_trial.h"
38#include "test/frame_generator.h"
39#include "test/frame_generator_capturer.h"
40#include "test/frame_utils.h"
41#include "test/gtest.h"
42#include "test/null_transport.h"
43#include "test/rtcp_packet_parser.h"
44#include "test/testsupport/perf_test.h"
perkjfa10b552016-10-02 23:45:26 -070045
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020046#include "video/send_statistics_proxy.h"
47#include "video/transport_adapter.h"
48#include "call/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000049
50namespace webrtc {
51
sprang@webrtc.org346094c2014-02-18 08:40:33 +000052enum VideoFormat { kGeneric, kVP8, };
53
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070054void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
55 const std::vector<VideoFrame>& frames2);
56VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000057
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000058class VideoSendStreamTest : public test::CallTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000059 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000060 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000061 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000062 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010063
64 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
65 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -070066
67 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000068};
69
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000070TEST_F(VideoSendStreamTest, CanStartStartedStream) {
eladalon413ee9a2017-08-22 04:02:52 -070071 task_queue_.SendTask([this]() {
72 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000073
eladalon413ee9a2017-08-22 04:02:52 -070074 test::NullTransport transport;
75 CreateSendConfig(1, 0, 0, &transport);
76 CreateVideoStreams();
77 video_send_stream_->Start();
78 video_send_stream_->Start();
79 DestroyStreams();
80 DestroyCalls();
81 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000082}
83
84TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
eladalon413ee9a2017-08-22 04:02:52 -070085 task_queue_.SendTask([this]() {
86 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000087
eladalon413ee9a2017-08-22 04:02:52 -070088 test::NullTransport transport;
89 CreateSendConfig(1, 0, 0, &transport);
90 CreateVideoStreams();
91 video_send_stream_->Stop();
92 video_send_stream_->Stop();
93 DestroyStreams();
94 DestroyCalls();
95 });
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000096}
97
pbos@webrtc.org013d9942013-08-22 09:42:17 +000098TEST_F(VideoSendStreamTest, SupportsCName) {
99 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000100 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000101 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000102 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000103
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000104 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000105 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -0700106 test::RtcpPacketParser parser;
107 EXPECT_TRUE(parser.Parse(packet, length));
108 if (parser.sdes()->num_packets() > 0) {
109 EXPECT_EQ(1u, parser.sdes()->chunks().size());
110 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000111
danilchap3dc929e2016-11-02 08:21:59 -0700112 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000113 }
114
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000115 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000116 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000117
stefanff483612015-12-21 03:14:00 -0800118 void ModifyVideoConfigs(
119 VideoSendStream::Config* send_config,
120 std::vector<VideoReceiveStream::Config>* receive_configs,
121 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000122 send_config->rtp.c_name = kCName;
123 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000124
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000125 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100126 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000127 }
128 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000129
stefane74eef12016-01-08 06:47:13 -0800130 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000131}
132
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000133TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000134 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000135 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000136 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000137 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100138 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000139 }
140
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000141 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000142 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000143 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000144
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000145 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
146 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
147 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700148 if (header.extension.absoluteSendTime != 0) {
149 // Wait for at least one packet with a non-zero send time. The send time
150 // is a 16-bit value derived from the system clock, and it is valid
151 // for a packet to have a zero send time. To tell that from an
152 // unpopulated value we'll wait for a packet with non-zero send time.
153 observation_complete_.Set();
154 } else {
155 LOG(LS_WARNING) << "Got a packet with zero absoluteSendTime, waiting"
156 " for another packet...";
157 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000158
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000159 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000160 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000161
stefanff483612015-12-21 03:14:00 -0800162 void ModifyVideoConfigs(
163 VideoSendStream::Config* send_config,
164 std::vector<VideoReceiveStream::Config>* receive_configs,
165 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200166 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100167 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700168 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000169 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000170
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000171 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100172 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000173 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000174 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000175
stefane74eef12016-01-08 06:47:13 -0800176 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000177}
178
pbos@webrtc.org29023282013-09-11 10:14:56 +0000179TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000180 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000181 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000182 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000183 TransmissionTimeOffsetObserver()
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000184 : SendTest(kDefaultTimeoutMs),
185 encoder_(Clock::GetRealTimeClock(), kEncodeDelayMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000186 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100187 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000188 }
189
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000190 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000191 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000192 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000193 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000194
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000195 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
196 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000197 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000198 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100199 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000200
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000201 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000202 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000203
stefanff483612015-12-21 03:14:00 -0800204 void ModifyVideoConfigs(
205 VideoSendStream::Config* send_config,
206 std::vector<VideoReceiveStream::Config>* receive_configs,
207 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000208 send_config->encoder_settings.encoder = &encoder_;
Stefan Holmer12952972015-10-29 15:13:24 +0100209 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700210 send_config->rtp.extensions.push_back(RtpExtension(
211 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000212 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000213
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000214 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100215 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000216 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000217
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000218 test::DelayedEncoder encoder_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000219 } test;
220
stefane74eef12016-01-08 06:47:13 -0800221 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000222}
223
sprang867fb522015-08-03 04:38:41 -0700224TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700225 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700226 class TransportWideSequenceNumberObserver : public test::SendTest {
227 public:
228 TransportWideSequenceNumberObserver()
229 : SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) {
230 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
231 kRtpExtensionTransportSequenceNumber, kExtensionId));
232 }
233
234 private:
235 Action OnSendRtp(const uint8_t* packet, size_t length) override {
236 RTPHeader header;
237 EXPECT_TRUE(parser_->Parse(packet, length, &header));
238
239 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
240 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
241 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
242
Peter Boström5811a392015-12-10 13:02:50 +0100243 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700244
245 return SEND_PACKET;
246 }
247
stefanff483612015-12-21 03:14:00 -0800248 void ModifyVideoConfigs(
249 VideoSendStream::Config* send_config,
250 std::vector<VideoReceiveStream::Config>* receive_configs,
251 VideoEncoderConfig* encoder_config) override {
sprang867fb522015-08-03 04:38:41 -0700252 send_config->encoder_settings.encoder = &encoder_;
sprang867fb522015-08-03 04:38:41 -0700253 }
254
255 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100256 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700257 }
258
259 test::FakeEncoder encoder_;
260 } test;
261
stefane74eef12016-01-08 06:47:13 -0800262 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700263}
264
perkj803d97f2016-11-01 11:45:46 -0700265TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
266 class VideoRotationObserver : public test::SendTest {
267 public:
268 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
269 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
270 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
271 }
272
273 Action OnSendRtp(const uint8_t* packet, size_t length) override {
274 RTPHeader header;
275 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700276 // Only the last packet of the frame is required to have the extension.
277 if (!header.markerBit)
278 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700279 EXPECT_TRUE(header.extension.hasVideoRotation);
280 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
281 observation_complete_.Set();
282 return SEND_PACKET;
283 }
284
285 void ModifyVideoConfigs(
286 VideoSendStream::Config* send_config,
287 std::vector<VideoReceiveStream::Config>* receive_configs,
288 VideoEncoderConfig* encoder_config) override {
289 send_config->rtp.extensions.clear();
290 send_config->rtp.extensions.push_back(RtpExtension(
291 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
292 }
293
294 void OnFrameGeneratorCapturerCreated(
295 test::FrameGeneratorCapturer* frame_generator_capturer) override {
296 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
297 }
298
299 void PerformTest() override {
300 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
301 }
302 } test;
303
304 RunBaseTest(&test);
305}
306
ilnik00d802b2017-04-11 10:34:31 -0700307TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700308 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700309 public:
ilnik10894992017-06-21 08:23:19 -0700310 VideoContentTypeObserver() : SendTest(kDefaultTimeoutMs) {
ilnik00d802b2017-04-11 10:34:31 -0700311 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
312 kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
313 }
314
315 Action OnSendRtp(const uint8_t* packet, size_t length) override {
316 RTPHeader header;
317 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700318 // Only the last packet of the frame must have extension.
319 if (!header.markerBit)
320 return SEND_PACKET;
ilnik00d802b2017-04-11 10:34:31 -0700321 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700322 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
323 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700324 observation_complete_.Set();
325 return SEND_PACKET;
326 }
327
328 void ModifyVideoConfigs(
329 VideoSendStream::Config* send_config,
330 std::vector<VideoReceiveStream::Config>* receive_configs,
331 VideoEncoderConfig* encoder_config) override {
332 send_config->rtp.extensions.clear();
333 send_config->rtp.extensions.push_back(
334 RtpExtension(RtpExtension::kVideoContentTypeUri,
335 test::kVideoContentTypeExtensionId));
336 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
337 }
338
339 void PerformTest() override {
340 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
341 }
342 } test;
343
344 RunBaseTest(&test);
345}
346
ilnik04f4d122017-06-19 07:18:55 -0700347TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700348 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700349 public:
ilnik10894992017-06-21 08:23:19 -0700350 VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
ilnik04f4d122017-06-19 07:18:55 -0700351 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
352 kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
353 }
354
355 Action OnSendRtp(const uint8_t* packet, size_t length) override {
356 RTPHeader header;
357 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700358 // Only the last packet of the frame must have extension.
359 if (!header.markerBit)
360 return SEND_PACKET;
361 EXPECT_TRUE(header.extension.has_video_timing);
362 observation_complete_.Set();
ilnik04f4d122017-06-19 07:18:55 -0700363 return SEND_PACKET;
364 }
365
366 void ModifyVideoConfigs(
367 VideoSendStream::Config* send_config,
368 std::vector<VideoReceiveStream::Config>* receive_configs,
369 VideoEncoderConfig* encoder_config) override {
370 send_config->rtp.extensions.clear();
371 send_config->rtp.extensions.push_back(RtpExtension(
372 RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
373 }
374
375 void PerformTest() override {
376 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
377 }
378 } test;
379
380 RunBaseTest(&test);
381}
382
danilchap901b2df2017-07-28 08:56:04 -0700383class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000384 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000385 FakeReceiveStatistics(uint32_t send_ssrc,
386 uint32_t last_sequence_number,
387 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700388 uint8_t fraction_lost) {
389 stat_.SetMediaSsrc(send_ssrc);
390 stat_.SetExtHighestSeqNum(last_sequence_number);
391 stat_.SetCumulativeLost(cumulative_lost);
392 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000393 }
394
danilchap901b2df2017-07-28 08:56:04 -0700395 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
396 EXPECT_GE(max_blocks, 1u);
397 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000398 }
399
400 private:
danilchap901b2df2017-07-28 08:56:04 -0700401 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000402};
403
brandtre602f0a2016-10-31 03:40:49 -0700404class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100405 public:
brandtre602f0a2016-10-31 03:40:49 -0700406 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800407 bool use_nack,
408 bool expect_red,
409 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800410 const std::string& codec,
411 VideoEncoder* encoder)
brandtr20d45472017-01-02 00:34:27 -0800412 : EndToEndTest(kTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800413 encoder_(encoder),
Peter Boström39593972016-02-15 11:27:15 +0100414 payload_name_(codec),
415 use_nack_(use_nack),
416 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700417 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800418 sent_media_(false),
419 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800420 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100421
brandtr20d45472017-01-02 00:34:27 -0800422 // Some of the test cases are expected to time out and thus we are using
423 // a shorter timeout window than the default here.
424 static constexpr size_t kTimeoutMs = 10000;
425
Stefan Holmer4654d202015-12-08 09:10:43 +0100426 private:
427 Action OnSendRtp(const uint8_t* packet, size_t length) override {
428 RTPHeader header;
429 EXPECT_TRUE(parser_->Parse(packet, length, &header));
430
Stefan Holmer4654d202015-12-08 09:10:43 +0100431 int encapsulated_payload_type = -1;
432 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100433 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100434 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
435 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100436 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100437 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
438 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100439 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100440 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100441 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
442 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100443 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
444 length) {
445 // Not padding-only, media received outside of RED.
446 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800447 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100448 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100449 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000450
Stefan Holmer4654d202015-12-08 09:10:43 +0100451 if (header_extensions_enabled_) {
452 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
453 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
454 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
455 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
456 // 24 bits wrap.
457 EXPECT_GT(prev_header_.extension.absoluteSendTime,
458 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000459 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100460 EXPECT_GE(header.extension.absoluteSendTime,
461 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200462 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100463 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
464 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
465 prev_header_.extension.transportSequenceNumber;
466 EXPECT_EQ(1, seq_num_diff);
467 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200468
Stefan Holmer4654d202015-12-08 09:10:43 +0100469 if (encapsulated_payload_type != -1) {
470 if (encapsulated_payload_type ==
471 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700472 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800473 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100474 } else {
brandtr65a1e772016-12-12 01:54:58 -0800475 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000476 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000477 }
478
brandtr20d45472017-01-02 00:34:27 -0800479 if (sent_media_ && sent_ulpfec_) {
480 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100481 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000482
Stefan Holmer4654d202015-12-08 09:10:43 +0100483 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000484
Stefan Holmer4654d202015-12-08 09:10:43 +0100485 return SEND_PACKET;
486 }
487
eladalon413ee9a2017-08-22 04:02:52 -0700488 test::PacketTransport* CreateSendTransport(
489 test::SingleThreadedTaskQueueForTesting* task_queue,
490 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100491 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
492 // Configure some network delay.
493 const int kNetworkDelayMs = 100;
494 FakeNetworkPipe::Config config;
brandtr65a1e772016-12-12 01:54:58 -0800495 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100496 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700497 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700498 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700499 VideoSendStreamTest::payload_type_map_, config);
Peter Boström39593972016-02-15 11:27:15 +0100500 }
501
stefanff483612015-12-21 03:14:00 -0800502 void ModifyVideoConfigs(
503 VideoSendStream::Config* send_config,
504 std::vector<VideoReceiveStream::Config>* receive_configs,
505 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100506 if (use_nack_) {
507 send_config->rtp.nack.rtp_history_ms =
508 (*receive_configs)[0].rtp.nack.rtp_history_ms =
509 VideoSendStreamTest::kNackRtpHistoryMs;
510 }
brandtr696c9c62016-12-19 05:47:28 -0800511 send_config->encoder_settings.encoder = encoder_;
Peter Boström39593972016-02-15 11:27:15 +0100512 send_config->encoder_settings.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700513 send_config->rtp.ulpfec.red_payload_type =
514 VideoSendStreamTest::kRedPayloadType;
515 send_config->rtp.ulpfec.ulpfec_payload_type =
516 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800517 EXPECT_FALSE(send_config->rtp.extensions.empty());
518 if (!header_extensions_enabled_) {
519 send_config->rtp.extensions.clear();
520 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100521 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700522 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100523 }
nisse3b3622f2017-09-26 02:49:21 -0700524 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700525 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700526 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700527 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100528 }
529
530 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800531 EXPECT_EQ(expect_ulpfec_, Wait())
532 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100533 }
534
brandtr696c9c62016-12-19 05:47:28 -0800535 VideoEncoder* const encoder_;
536 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100537 const bool use_nack_;
538 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700539 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800540 bool sent_media_;
541 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100542 bool header_extensions_enabled_;
543 RTPHeader prev_header_;
544};
545
brandtre602f0a2016-10-31 03:40:49 -0700546TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800547 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
548 UlpfecObserver test(true, false, true, true, "VP8", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800549 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100550}
551
brandtre602f0a2016-10-31 03:40:49 -0700552TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800553 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
554 UlpfecObserver test(false, false, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100555 RunBaseTest(&test);
556}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000557
stefan60e10c72017-08-23 10:40:00 -0700558class VideoSendStreamWithoutUlpfecTest : public VideoSendStreamTest {
559 protected:
560 VideoSendStreamWithoutUlpfecTest()
561 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
562
563 test::ScopedFieldTrials field_trial_;
564};
565
566TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
567 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
568 UlpfecObserver test(false, false, true, false, "VP8", encoder.get());
569 RunBaseTest(&test);
570}
571
Peter Boström39593972016-02-15 11:27:15 +0100572// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
573// since we'll still have to re-request FEC packets, effectively wasting
574// bandwidth since the receiver has to wait for FEC retransmissions to determine
575// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700576TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800577 std::unique_ptr<VideoEncoder> encoder(
578 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
579 UlpfecObserver test(false, true, true, false, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100580 RunBaseTest(&test);
581}
582
583// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800584TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800585 std::unique_ptr<VideoEncoder> encoder(
586 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
587 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100588 RunBaseTest(&test);
589}
590
danilchap9f5b6222017-03-02 06:22:21 -0800591// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
592TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800593 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
594 UlpfecObserver test(false, true, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100595 RunBaseTest(&test);
596}
597
Peter Boström12996152016-05-14 02:03:18 +0200598#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800599// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
600TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800601 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
602 UlpfecObserver test(false, true, true, true, "VP9", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800603 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000604}
Peter Boström12996152016-05-14 02:03:18 +0200605#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000606
brandtre78d2662017-01-16 05:57:16 -0800607TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800608 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800609 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800610 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
611 RunBaseTest(&test);
612}
613
brandtr39f97292016-11-16 22:57:50 -0800614// TODO(brandtr): Move these FlexFEC tests when we have created
615// FlexfecSendStream.
616class FlexfecObserver : public test::EndToEndTest {
617 public:
618 FlexfecObserver(bool header_extensions_enabled,
619 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800620 const std::string& codec,
621 VideoEncoder* encoder)
brandtr39f97292016-11-16 22:57:50 -0800622 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800623 encoder_(encoder),
brandtr39f97292016-11-16 22:57:50 -0800624 payload_name_(codec),
625 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800626 sent_media_(false),
627 sent_flexfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800628 header_extensions_enabled_(header_extensions_enabled) {}
brandtr39f97292016-11-16 22:57:50 -0800629
630 size_t GetNumFlexfecStreams() const override { return 1; }
631
632 private:
633 Action OnSendRtp(const uint8_t* packet, size_t length) override {
634 RTPHeader header;
635 EXPECT_TRUE(parser_->Parse(packet, length, &header));
636
brandtr39f97292016-11-16 22:57:50 -0800637 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
638 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
639 sent_flexfec_ = true;
640 } else {
641 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
642 header.payloadType);
643 EXPECT_EQ(VideoSendStreamTest::kVideoSendSsrcs[0], header.ssrc);
644 sent_media_ = true;
645 }
646
647 if (header_extensions_enabled_) {
648 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
649 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
650 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
651 }
652
brandtr0c5a1542016-11-23 04:42:26 -0800653 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800654 observation_complete_.Set();
655 }
656
657 return SEND_PACKET;
658 }
659
eladalon413ee9a2017-08-22 04:02:52 -0700660 test::PacketTransport* CreateSendTransport(
661 test::SingleThreadedTaskQueueForTesting* task_queue,
662 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800663 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
664 // Therefore we need some network delay.
665 const int kNetworkDelayMs = 100;
666 FakeNetworkPipe::Config config;
brandtrd654a9b2016-12-05 05:38:19 -0800667 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800668 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700669 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700670 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700671 VideoSendStreamTest::payload_type_map_, config);
brandtr39f97292016-11-16 22:57:50 -0800672 }
673
674 void ModifyVideoConfigs(
675 VideoSendStream::Config* send_config,
676 std::vector<VideoReceiveStream::Config>* receive_configs,
677 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800678 if (use_nack_) {
679 send_config->rtp.nack.rtp_history_ms =
680 (*receive_configs)[0].rtp.nack.rtp_history_ms =
681 VideoSendStreamTest::kNackRtpHistoryMs;
682 }
brandtr696c9c62016-12-19 05:47:28 -0800683 send_config->encoder_settings.encoder = encoder_;
brandtr39f97292016-11-16 22:57:50 -0800684 send_config->encoder_settings.payload_name = payload_name_;
685 if (header_extensions_enabled_) {
686 send_config->rtp.extensions.push_back(RtpExtension(
687 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
688 send_config->rtp.extensions.push_back(RtpExtension(
689 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800690 } else {
691 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800692 }
693 }
694
695 void PerformTest() override {
696 EXPECT_TRUE(Wait())
697 << "Timed out waiting for FlexFEC and/or media packets.";
698 }
699
brandtr696c9c62016-12-19 05:47:28 -0800700 VideoEncoder* const encoder_;
701 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800702 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800703 bool sent_media_;
704 bool sent_flexfec_;
705 bool header_extensions_enabled_;
706};
707
brandtrd654a9b2016-12-05 05:38:19 -0800708TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800709 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
710 FlexfecObserver test(false, false, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800711 RunBaseTest(&test);
712}
713
714TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800715 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
716 FlexfecObserver test(false, true, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800717 RunBaseTest(&test);
718}
719
brandtr39f97292016-11-16 22:57:50 -0800720TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800721 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
722 FlexfecObserver test(true, false, "VP8", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800723 RunBaseTest(&test);
724}
725
brandtr39f97292016-11-16 22:57:50 -0800726#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800727TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800728 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
729 FlexfecObserver test(false, false, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800730 RunBaseTest(&test);
731}
732
brandtrd654a9b2016-12-05 05:38:19 -0800733TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800734 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
735 FlexfecObserver test(false, true, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800736 RunBaseTest(&test);
737}
738#endif // defined(RTC_DISABLE_VP9)
739
brandtrd654a9b2016-12-05 05:38:19 -0800740TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
brandtr696c9c62016-12-19 05:47:28 -0800741 std::unique_ptr<VideoEncoder> encoder(
742 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
743 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800744 RunBaseTest(&test);
745}
746
brandtrd654a9b2016-12-05 05:38:19 -0800747TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
brandtr696c9c62016-12-19 05:47:28 -0800748 std::unique_ptr<VideoEncoder> encoder(
749 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
750 FlexfecObserver test(false, true, "H264", encoder.get());
751 RunBaseTest(&test);
752}
753
brandtre78d2662017-01-16 05:57:16 -0800754TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800755 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800756 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800757 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800758 RunBaseTest(&test);
759}
760
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000761void VideoSendStreamTest::TestNackRetransmission(
762 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000763 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000764 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000765 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000766 explicit NackObserver(uint32_t retransmit_ssrc,
767 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000768 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000769 send_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000770 retransmit_ssrc_(retransmit_ssrc),
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000771 retransmit_payload_type_(retransmit_payload_type),
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000772 nacked_sequence_number_(-1) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000773 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000774
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000775 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000776 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000777 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000778 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000779
780 // Nack second packet after receiving the third one.
781 if (++send_count_ == 3) {
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000782 uint16_t nack_sequence_number = header.sequenceNumber - 1;
783 nacked_sequence_number_ = nack_sequence_number;
danilchap8a1d2a32017-08-01 03:21:37 -0700784 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
terelius429c3452016-01-21 05:42:04 -0800785 nullptr, nullptr, transport_adapter_.get());
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000786
pbosda903ea2015-10-02 02:36:56 -0700787 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100788 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000789
790 RTCPSender::FeedbackState feedback_state;
791
792 EXPECT_EQ(0,
793 rtcp_sender.SendRTCP(
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000794 feedback_state, kRtcpNack, 1, &nack_sequence_number));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000795 }
796
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000797 uint16_t sequence_number = header.sequenceNumber;
798
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000799 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100800 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
801 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000802 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000803 const uint8_t* rtx_header = packet + header.headerLength;
804 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
805 }
806
807 if (sequence_number == nacked_sequence_number_) {
808 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000809 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
Peter Boström5811a392015-12-10 13:02:50 +0100810 observation_complete_.Set();
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000811 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000812
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000813 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000814 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000815
stefanff483612015-12-21 03:14:00 -0800816 void ModifyVideoConfigs(
817 VideoSendStream::Config* send_config,
818 std::vector<VideoReceiveStream::Config>* receive_configs,
819 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700820 transport_adapter_.reset(
821 new internal::TransportAdapter(send_config->send_transport));
822 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000823 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000824 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100825 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000826 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
827 }
828
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000829 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100830 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000831 }
832
kwiberg27f982b2016-03-01 11:52:33 -0800833 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000834 int send_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000835 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000836 uint8_t retransmit_payload_type_;
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000837 int nacked_sequence_number_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000838 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000839
stefane74eef12016-01-08 06:47:13 -0800840 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000841}
842
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000843TEST_F(VideoSendStreamTest, RetransmitsNack) {
844 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100845 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000846}
847
848TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
849 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000850 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000851}
852
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000853void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
854 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000855 // Use a fake encoder to output a frame of every size in the range [90, 290],
856 // for each size making sure that the exact number of payload bytes received
857 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000858 static const size_t kMaxPacketSize = 128;
859 static const size_t start = 90;
860 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000861
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000862 // Observer that verifies that the expected number of packets and bytes
863 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000864 class FrameFragmentationTest : public test::SendTest,
865 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000866 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000867 FrameFragmentationTest(size_t max_packet_size,
868 size_t start_size,
869 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000870 bool test_generic_packetization,
871 bool use_fec)
872 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000873 encoder_(stop),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000874 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000875 stop_size_(stop_size),
876 test_generic_packetization_(test_generic_packetization),
877 use_fec_(use_fec),
878 packet_count_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000879 accumulated_size_(0),
880 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000881 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000882 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700883 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000884 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000885 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700886 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000887 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000888
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000889 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000890 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000891 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000892 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000893 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000894
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000895 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000896
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000897 if (use_fec_) {
898 uint8_t payload_type = packet[header.headerLength];
899 bool is_fec = header.payloadType == kRedPayloadType &&
900 payload_type == kUlpfecPayloadType;
901 if (is_fec) {
902 fec_packet_received_ = true;
903 return SEND_PACKET;
904 }
905 }
906
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000907 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000908
909 if (use_fec_)
910 TriggerLossReport(header);
911
912 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200913 size_t overhead = header.headerLength + header.paddingLength;
914 // Only remove payload header and RED header if the packet actually
915 // contains payload.
916 if (length > overhead) {
917 overhead += (1 /* Generic header */);
918 if (use_fec_)
919 overhead += 1; // RED for FEC header.
920 }
921 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000922 accumulated_payload_ += length - overhead;
923 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000924
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000925 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000926 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000927 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
928 // With FEC enabled, frame size is incremented asynchronously, so
929 // "old" frames one byte too small may arrive. Accept, but don't
930 // increase expected frame size.
931 accumulated_size_ = 0;
932 accumulated_payload_ = 0;
933 return SEND_PACKET;
934 }
935
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000936 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000937 if (test_generic_packetization_) {
938 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
939 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000940
941 // Last packet of frame; reset counters.
942 accumulated_size_ = 0;
943 accumulated_payload_ = 0;
944 if (current_size_rtp_ == stop_size_) {
945 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +0100946 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000947 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000948 // Increase next expected frame size. If testing with FEC, make sure
949 // a FEC packet has been received for this frame size before
950 // proceeding, to make sure that redundancy packets don't exceed
951 // size limit.
952 if (!use_fec_) {
953 ++current_size_rtp_;
954 } else if (fec_packet_received_) {
955 fec_packet_received_ = false;
956 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700957
958 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000959 ++current_size_frame_;
960 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000961 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000962 }
963
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000964 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000965 }
966
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000967 void TriggerLossReport(const RTPHeader& header) {
968 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -0700969 const int kLossPercent = 5;
970 if (packet_count_++ % (100 / kLossPercent) != 0) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000971 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -0700972 kVideoSendSsrcs[0], header.sequenceNumber,
973 (packet_count_ * (100 - kLossPercent)) / 100, // Cumulative lost.
974 static_cast<uint8_t>((255 * kLossPercent) / 100)); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +0200975 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -0800976 &lossy_receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -0700977 transport_adapter_.get());
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000978
pbosda903ea2015-10-02 02:36:56 -0700979 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100980 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000981
982 RTCPSender::FeedbackState feedback_state;
983
984 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
985 }
986 }
987
nisseef8b61e2016-04-29 06:09:15 -0700988 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700989 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000990 // Increase frame size for next encoded frame, in the context of the
991 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700992 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000993 ++current_size_frame_;
994 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700995 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000996 }
997
Stefan Holmere5904162015-03-26 11:11:06 +0100998 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -0700999 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01001000 const int kMinBitrateBps = 30000;
1001 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
1002 return config;
1003 }
1004
stefanff483612015-12-21 03:14:00 -08001005 void ModifyVideoConfigs(
1006 VideoSendStream::Config* send_config,
1007 std::vector<VideoReceiveStream::Config>* receive_configs,
1008 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001009 transport_adapter_.reset(
1010 new internal::TransportAdapter(send_config->send_transport));
1011 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001012 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001013 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1014 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001015 }
1016
1017 if (!test_generic_packetization_)
1018 send_config->encoder_settings.payload_name = "VP8";
1019
1020 send_config->encoder_settings.encoder = &encoder_;
1021 send_config->rtp.max_packet_size = kMaxPacketSize;
1022 send_config->post_encode_callback = this;
1023
Erik Språng95261872015-04-10 11:58:49 +02001024 // Make sure there is at least one extension header, to make the RTP
1025 // header larger than the base length of 12 bytes.
1026 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001027
1028 // Setup screen content disables frame dropping which makes this easier.
1029 class VideoStreamFactory
1030 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1031 public:
1032 explicit VideoStreamFactory(size_t num_temporal_layers)
1033 : num_temporal_layers_(num_temporal_layers) {
1034 EXPECT_GT(num_temporal_layers, 0u);
1035 }
1036
1037 private:
1038 std::vector<VideoStream> CreateEncoderStreams(
1039 int width,
1040 int height,
1041 const VideoEncoderConfig& encoder_config) override {
1042 std::vector<VideoStream> streams =
1043 test::CreateVideoStreams(width, height, encoder_config);
1044 for (VideoStream& stream : streams) {
1045 stream.temporal_layer_thresholds_bps.resize(num_temporal_layers_ -
1046 1);
1047 }
1048 return streams;
1049 }
1050 const size_t num_temporal_layers_;
1051 };
1052
1053 encoder_config->video_stream_factory =
1054 new rtc::RefCountedObject<VideoStreamFactory>(2);
1055 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001056 }
1057
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001058 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001059 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001060 }
1061
kwiberg27f982b2016-03-01 11:52:33 -08001062 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001063 test::ConfigurableFrameSizeEncoder encoder_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001064
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001065 const size_t max_packet_size_;
1066 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001067 const bool test_generic_packetization_;
1068 const bool use_fec_;
1069
1070 uint32_t packet_count_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001071 size_t accumulated_size_;
1072 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001073 bool fec_packet_received_;
1074
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001075 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001076 rtc::CriticalSection mutex_;
1077 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001078 };
1079
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001080 // Don't auto increment if FEC is used; continue sending frame size until
1081 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001082 FrameFragmentationTest test(
1083 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001084
stefane74eef12016-01-08 06:47:13 -08001085 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001086}
1087
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001088// TODO(sprang): Is there any way of speeding up these tests?
1089TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
1090 TestPacketFragmentationSize(kGeneric, false);
1091}
1092
1093TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
1094 TestPacketFragmentationSize(kGeneric, true);
1095}
1096
1097TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
1098 TestPacketFragmentationSize(kVP8, false);
1099}
1100
1101TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
1102 TestPacketFragmentationSize(kVP8, true);
1103}
1104
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001105// The test will go through a number of phases.
1106// 1. Start sending packets.
1107// 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 +00001108// suspend the stream.
1109// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001110// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001111// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001112// When the stream is detected again, and the stats show that the stream
1113// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001114TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1115 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001116
nissed30a1112016-04-18 05:15:22 -07001117 class RembObserver : public test::SendTest,
1118 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001119 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001120 RembObserver()
1121 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001122 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001123 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001124 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001125 rtp_count_(0),
1126 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001127 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001128 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001129 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001130
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001131 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001132 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001133 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001134 ++rtp_count_;
1135 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001136 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001137 last_sequence_number_ = header.sequenceNumber;
1138
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001139 if (test_state_ == kBeforeSuspend) {
1140 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001141 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001142 test_state_ = kDuringSuspend;
1143 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001144 if (header.paddingLength == 0) {
1145 // Received non-padding packet during suspension period. Reset the
1146 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001147 suspended_frame_count_ = 0;
1148 }
stefanf116bd02015-10-27 08:29:42 -07001149 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001150 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001151 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001152 // Non-padding packet observed. Test is almost complete. Will just
1153 // have to wait for the stats to change.
1154 test_state_ = kWaitingForStats;
1155 }
stefanf116bd02015-10-27 08:29:42 -07001156 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001157 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001158 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001159 if (stats.suspended == false) {
1160 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001161 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001162 }
stefanf116bd02015-10-27 08:29:42 -07001163 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001164 }
1165
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001166 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001167 }
1168
perkj26091b12016-09-01 01:17:40 -07001169 // This method implements the rtc::VideoSinkInterface. This is called when
1170 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001171 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001172 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001173 if (test_state_ == kDuringSuspend &&
1174 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001175 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001176 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001177 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001178 test_state_ = kWaitingForPacket;
1179 }
1180 }
1181
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001182 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001183 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001184 low_remb_bps_ = value;
1185 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001186
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001187 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001188 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001189 high_remb_bps_ = value;
1190 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001191
stefanff483612015-12-21 03:14:00 -08001192 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001193 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001194 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001195 stream_ = send_stream;
1196 }
1197
stefanff483612015-12-21 03:14:00 -08001198 void ModifyVideoConfigs(
1199 VideoSendStream::Config* send_config,
1200 std::vector<VideoReceiveStream::Config>* receive_configs,
1201 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001202 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001203 transport_adapter_.reset(
1204 new internal::TransportAdapter(send_config->send_transport));
1205 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001206 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001207 send_config->pre_encode_callback = this;
1208 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001209 int min_bitrate_bps =
1210 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001211 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001212 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001213 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001214 min_bitrate_bps + threshold_window + 5000);
1215 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1216 }
1217
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001218 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001219 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001220 }
1221
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001222 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001223 kBeforeSuspend,
1224 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001225 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001226 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001227 };
1228
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001229 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001230 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001231 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1232 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001233 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -07001234 transport_adapter_.get());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001235
pbosda903ea2015-10-02 02:36:56 -07001236 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001237 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001238 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001239 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001240 }
1241 RTCPSender::FeedbackState feedback_state;
1242 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1243 }
1244
kwiberg27f982b2016-03-01 11:52:33 -08001245 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001246 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001247 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001248
Peter Boströmf2f82832015-05-01 13:00:41 +02001249 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001250 TestState test_state_ RTC_GUARDED_BY(crit_);
1251 int rtp_count_ RTC_GUARDED_BY(crit_);
1252 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1253 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1254 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1255 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001256 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001257
stefane74eef12016-01-08 06:47:13 -08001258 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001259}
1260
perkj71ee44c2016-06-15 00:47:53 -07001261// This test that padding stops being send after a while if the Camera stops
1262// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001263TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001264 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001265 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001266 NoPaddingWhenVideoIsMuted()
1267 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001268 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001269 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001270 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +00001271 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001272
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001273 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001274 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001275 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001276 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001277
1278 RTPHeader header;
1279 parser_->Parse(packet, length, &header);
1280 const bool only_padding =
1281 header.headerLength + header.paddingLength == length;
1282
1283 if (test_state_ == kBeforeStopCapture) {
1284 capturer_->Stop();
1285 test_state_ = kWaitingForPadding;
1286 } else if (test_state_ == kWaitingForPadding && only_padding) {
1287 test_state_ = kWaitingForNoPackets;
1288 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1289 only_padding) {
1290 observation_complete_.Set();
1291 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001292 return SEND_PACKET;
1293 }
1294
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001295 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001296 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001297 const int kNoPacketsThresholdMs = 2000;
1298 if (test_state_ == kWaitingForNoPackets &&
1299 (last_packet_time_ms_ > 0 &&
1300 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1301 kNoPacketsThresholdMs)) {
1302 capturer_->Start();
1303 test_state_ = kWaitingForPaddingAfterCameraRestart;
1304 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001305 return SEND_PACKET;
1306 }
1307
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001308 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001309
nisseef8b61e2016-04-29 06:09:15 -07001310 void OnFrameGeneratorCapturerCreated(
1311 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001312 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001313 capturer_ = frame_generator_capturer;
1314 }
1315
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001316 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001317 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001318 << "Timed out while waiting for RTP packets to stop being sent.";
1319 }
1320
perkj71ee44c2016-06-15 00:47:53 -07001321 enum TestState {
1322 kBeforeStopCapture,
1323 kWaitingForPadding,
1324 kWaitingForNoPackets,
1325 kWaitingForPaddingAfterCameraRestart
1326 };
1327
1328 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001329 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001330 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001331 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001332 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1333 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001334 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001335
stefane74eef12016-01-08 06:47:13 -08001336 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001337}
1338
isheriffcc5903e2016-10-04 08:29:38 -07001339TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1340 const int kCapacityKbps = 10000; // 10 Mbps
1341 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1342 public:
1343 PaddingIsPrimarilyRetransmissions()
1344 : EndToEndTest(kDefaultTimeoutMs),
1345 clock_(Clock::GetRealTimeClock()),
1346 padding_length_(0),
1347 total_length_(0),
1348 call_(nullptr) {}
1349
1350 private:
1351 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1352 call_ = sender_call;
1353 }
1354
1355 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1356 rtc::CritScope lock(&crit_);
1357
1358 RTPHeader header;
1359 parser_->Parse(packet, length, &header);
1360 padding_length_ += header.paddingLength;
1361 total_length_ += length;
1362 return SEND_PACKET;
1363 }
1364
eladalon413ee9a2017-08-22 04:02:52 -07001365 test::PacketTransport* CreateSendTransport(
1366 test::SingleThreadedTaskQueueForTesting* task_queue,
1367 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001368 const int kNetworkDelayMs = 50;
1369 FakeNetworkPipe::Config config;
1370 config.loss_percent = 10;
1371 config.link_capacity_kbps = kCapacityKbps;
1372 config.queue_delay_ms = kNetworkDelayMs;
eladalon413ee9a2017-08-22 04:02:52 -07001373 return new test::PacketTransport(task_queue, sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -07001374 test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -07001375 payload_type_map_, config);
isheriffcc5903e2016-10-04 08:29:38 -07001376 }
1377
1378 void ModifyVideoConfigs(
1379 VideoSendStream::Config* send_config,
1380 std::vector<VideoReceiveStream::Config>* receive_configs,
1381 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001382 // Turn on RTX.
1383 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1384 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001385 }
1386
1387 void PerformTest() override {
1388 // TODO(isheriff): Some platforms do not ramp up as expected to full
1389 // capacity due to packet scheduling delays. Fix that before getting
1390 // rid of this.
1391 SleepMs(5000);
1392 {
1393 rtc::CritScope lock(&crit_);
1394 // Expect padding to be a small percentage of total bytes sent.
1395 EXPECT_LT(padding_length_, .1 * total_length_);
1396 }
1397 }
1398
1399 rtc::CriticalSection crit_;
1400 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001401 size_t padding_length_ RTC_GUARDED_BY(crit_);
1402 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001403 Call* call_;
1404 } test;
1405
1406 RunBaseTest(&test);
1407}
1408
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001409// This test first observes "high" bitrate use at which point it sends a REMB to
1410// indicate that it should be lowered significantly. The test then observes that
1411// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1412// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001413//
1414// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1415// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001416TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1417 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001418 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001419 static const int kRembBitrateBps = 80000;
1420 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001421 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001422 public:
1423 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001424 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001425 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1426 stream_(nullptr),
1427 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001428
1429 private:
nisseef8b61e2016-04-29 06:09:15 -07001430 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001431 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001432 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001433
1434 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001435 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001436 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001437 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001438 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001439 if (!stats.substreams.empty()) {
1440 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001441 int total_bitrate_bps =
1442 stats.substreams.begin()->second.total_bitrate_bps;
1443 test::PrintResult("bitrate_stats_",
1444 "min_transmit_bitrate_low_remb",
1445 "bitrate_bps",
1446 static_cast<size_t>(total_bitrate_bps),
1447 "bps",
1448 false);
1449 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001450 rtp_rtcp_->SetRemb(kRembBitrateBps,
1451 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001452 rtp_rtcp_->Process();
1453 bitrate_capped_ = true;
1454 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001455 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001456 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001457 }
1458 }
stefanf116bd02015-10-27 08:29:42 -07001459 // Packets don't have to be delivered since the test is the receiver.
1460 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001461 }
1462
stefanff483612015-12-21 03:14:00 -08001463 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001464 VideoSendStream* send_stream,
1465 const std::vector<VideoReceiveStream*>& receive_streams) override {
1466 stream_ = send_stream;
1467 RtpRtcp::Configuration config;
1468 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001469 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001470 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
stefanf116bd02015-10-27 08:29:42 -07001471 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001472 }
1473
stefanff483612015-12-21 03:14:00 -08001474 void ModifyVideoConfigs(
1475 VideoSendStream::Config* send_config,
1476 std::vector<VideoReceiveStream::Config>* receive_configs,
1477 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001478 feedback_transport_.reset(
1479 new internal::TransportAdapter(send_config->send_transport));
1480 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001481 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001482 }
1483
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001484 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001485 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001486 << "Timeout while waiting for low bitrate stats after REMB.";
1487 }
1488
kwiberg27f982b2016-03-01 11:52:33 -08001489 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1490 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001491 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001492 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001493 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001494 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001495
stefane74eef12016-01-08 06:47:13 -08001496 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001497}
1498
Stefan Holmer280de9e2016-09-30 10:06:51 +02001499TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1500 static const int kStartBitrateBps = 300000;
1501 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001502 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001503 class ChangingNetworkRouteTest : public test::EndToEndTest {
1504 public:
eladalon413ee9a2017-08-22 04:02:52 -07001505 explicit ChangingNetworkRouteTest(
1506 test::SingleThreadedTaskQueueForTesting* task_queue)
1507 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1508 task_queue_(task_queue),
1509 call_(nullptr) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001510 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1511 kRtpExtensionTransportSequenceNumber, kExtensionId));
1512 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001513
1514 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1515 call_ = sender_call;
1516 }
1517
Stefan Holmer280de9e2016-09-30 10:06:51 +02001518 void ModifyVideoConfigs(
1519 VideoSendStream::Config* send_config,
1520 std::vector<VideoReceiveStream::Config>* receive_configs,
1521 VideoEncoderConfig* encoder_config) override {
1522 send_config->rtp.extensions.clear();
1523 send_config->rtp.extensions.push_back(RtpExtension(
1524 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1525 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1526 (*receive_configs)[0].rtp.transport_cc = true;
1527 }
1528
1529 void ModifyAudioConfigs(
1530 AudioSendStream::Config* send_config,
1531 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1532 send_config->rtp.extensions.clear();
1533 send_config->rtp.extensions.push_back(RtpExtension(
1534 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1535 (*receive_configs)[0].rtp.extensions.clear();
1536 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1537 (*receive_configs)[0].rtp.transport_cc = true;
1538 }
1539
Stefan Holmerbe402962016-07-08 16:16:41 +02001540 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1541 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1542 observation_complete_.Set();
1543 }
1544
1545 return SEND_PACKET;
1546 }
1547
1548 void PerformTest() override {
1549 rtc::NetworkRoute new_route(true, 10, 20, -1);
Stefan Holmerbe402962016-07-08 16:16:41 +02001550 Call::Config::BitrateConfig bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001551
1552 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1553 call_->OnNetworkRouteChanged("transport", new_route);
1554 bitrate_config.start_bitrate_bps = kStartBitrateBps;
1555 call_->SetBitrateConfig(bitrate_config);
1556 });
1557
Stefan Holmerbe402962016-07-08 16:16:41 +02001558 EXPECT_TRUE(Wait())
1559 << "Timed out while waiting for start bitrate to be exceeded.";
1560
eladalon413ee9a2017-08-22 04:02:52 -07001561 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1562 bitrate_config.start_bitrate_bps = -1;
1563 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
1564 call_->SetBitrateConfig(bitrate_config);
1565 // TODO(holmer): We should set the last sent packet id here and verify
1566 // that we correctly ignore any packet loss reported prior to that id.
1567 ++new_route.local_network_id;
1568 call_->OnNetworkRouteChanged("transport", new_route);
1569 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1570 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001571 }
1572
1573 private:
eladalon413ee9a2017-08-22 04:02:52 -07001574 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Stefan Holmerbe402962016-07-08 16:16:41 +02001575 Call* call_;
eladalon413ee9a2017-08-22 04:02:52 -07001576 } test(&task_queue_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001577
1578 RunBaseTest(&test);
1579}
1580
michaelt79e05882016-11-08 02:50:09 -08001581TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
1582 class ChangingTransportOverheadTest : public test::EndToEndTest {
1583 public:
eladalon413ee9a2017-08-22 04:02:52 -07001584 explicit ChangingTransportOverheadTest(
1585 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001586 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001587 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001588 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001589 packets_sent_(0),
1590 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001591
1592 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1593 call_ = sender_call;
1594 }
1595
1596 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001597 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001598 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001599 if (++packets_sent_ < 100)
1600 return SEND_PACKET;
1601 observation_complete_.Set();
1602 return SEND_PACKET;
1603 }
1604
michaelta3328772016-11-29 09:25:03 -08001605 void ModifyVideoConfigs(
1606 VideoSendStream::Config* send_config,
1607 std::vector<VideoReceiveStream::Config>* receive_configs,
1608 VideoEncoderConfig* encoder_config) override {
1609 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1610 }
1611
michaelt79e05882016-11-08 02:50:09 -08001612 void PerformTest() override {
eladalon413ee9a2017-08-22 04:02:52 -07001613 task_queue_->SendTask([this]() {
1614 transport_overhead_ = 100;
1615 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1616 transport_overhead_);
1617 });
1618
michaelt79e05882016-11-08 02:50:09 -08001619 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001620
sprang21253fc2017-02-27 03:35:47 -08001621 {
1622 rtc::CritScope cs(&lock_);
1623 packets_sent_ = 0;
1624 }
eladalon413ee9a2017-08-22 04:02:52 -07001625
1626 task_queue_->SendTask([this]() {
1627 transport_overhead_ = 500;
1628 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1629 transport_overhead_);
1630 });
1631
michaelt79e05882016-11-08 02:50:09 -08001632 EXPECT_TRUE(Wait());
1633 }
1634
1635 private:
eladalon413ee9a2017-08-22 04:02:52 -07001636 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001637 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001638 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001639 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001640 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001641 const size_t kMaxRtpPacketSize = 1000;
eladalon413ee9a2017-08-22 04:02:52 -07001642 } test(&task_queue_);
michaelt79e05882016-11-08 02:50:09 -08001643
1644 RunBaseTest(&test);
1645}
1646
sprangf24a0642017-02-28 13:23:26 -08001647// Test class takes takes as argument a switch selecting if type switch should
1648// occur and a function pointer to reset the send stream. This is necessary
1649// since you cannot change the content type of a VideoSendStream, you need to
1650// recreate it. Stopping and recreating the stream can only be done on the main
1651// thread and in the context of VideoSendStreamTest (not BaseTest).
1652template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001653class MaxPaddingSetTest : public test::SendTest {
1654 public:
1655 static const uint32_t kMinTransmitBitrateBps = 400000;
1656 static const uint32_t kActualEncodeBitrateBps = 40000;
1657 static const uint32_t kMinPacketsToSend = 50;
1658
sprangf24a0642017-02-28 13:23:26 -08001659 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001660 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001661 content_switch_event_(false, false),
sprang9c0b5512016-07-06 00:54:28 -07001662 call_(nullptr),
1663 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001664 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001665 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001666 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001667 stream_resetter_(stream_reset_fun) {
1668 RTC_DCHECK(stream_resetter_);
1669 }
sprang9c0b5512016-07-06 00:54:28 -07001670
1671 void OnVideoStreamsCreated(
1672 VideoSendStream* send_stream,
1673 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001674 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001675 send_stream_ = send_stream;
1676 }
1677
1678 void ModifyVideoConfigs(
1679 VideoSendStream::Config* send_config,
1680 std::vector<VideoReceiveStream::Config>* receive_configs,
1681 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001682 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001683 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001684 encoder_config->min_transmit_bitrate_bps = 0;
1685 encoder_config->content_type =
1686 VideoEncoderConfig::ContentType::kRealtimeVideo;
1687 } else {
1688 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1689 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1690 }
sprangf24a0642017-02-28 13:23:26 -08001691 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001692 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001693 }
1694
1695 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1696 call_ = sender_call;
1697 }
1698
1699 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1700 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001701 if (running_without_padding_)
1702 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1703
1704 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1705 // we have reliable data.
1706 if (++packets_sent_ < kMinPacketsToSend)
1707 return SEND_PACKET;
1708
1709 if (running_without_padding_) {
1710 // We've sent kMinPacketsToSend packets with default configuration, switch
1711 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001712 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001713 packets_sent_ = 0;
1714 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1715 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001716 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001717 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001718 return SEND_PACKET;
1719 }
1720
1721 // Make sure the pacer has been configured with a min transmit bitrate.
1722 if (call_->GetStats().max_padding_bitrate_bps > 0)
1723 observation_complete_.Set();
1724
1725 return SEND_PACKET;
1726 }
1727
1728 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001729 if (RunningWithoutPadding()) {
1730 ASSERT_TRUE(
1731 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001732 (*stream_resetter_)(send_stream_config_, encoder_config_);
1733 }
1734
sprang9c0b5512016-07-06 00:54:28 -07001735 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1736 }
1737
1738 private:
sprangf24a0642017-02-28 13:23:26 -08001739 bool RunningWithoutPadding() const {
1740 rtc::CritScope lock(&crit_);
1741 return running_without_padding_;
1742 }
1743
sprang9c0b5512016-07-06 00:54:28 -07001744 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001745 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001746 Call* call_;
danilchapa37de392017-09-09 04:17:22 -07001747 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
sprangf24a0642017-02-28 13:23:26 -08001748 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001749 VideoEncoderConfig encoder_config_;
danilchapa37de392017-09-09 04:17:22 -07001750 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
sprang9c0b5512016-07-06 00:54:28 -07001751 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001752 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001753};
1754
1755TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001756 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1757 const VideoEncoderConfig& encoder_config) {};
1758 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001759 RunBaseTest(&test);
1760}
1761
1762TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001763 // Function for removing and recreating the send stream with a new config.
1764 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1765 const VideoEncoderConfig& encoder_config) {
eladalon413ee9a2017-08-22 04:02:52 -07001766 task_queue_.SendTask([this, &send_stream_config, &encoder_config]() {
1767 Stop();
1768 sender_call_->DestroyVideoSendStream(video_send_stream_);
1769 video_send_config_ = send_stream_config.Copy();
1770 video_encoder_config_ = encoder_config.Copy();
1771 video_send_stream_ = sender_call_->CreateVideoSendStream(
1772 video_send_config_.Copy(), video_encoder_config_.Copy());
1773 video_send_stream_->SetSource(
1774 frame_generator_capturer_.get(),
1775 VideoSendStream::DegradationPreference::kMaintainResolution);
1776 Start();
1777 });
sprangf24a0642017-02-28 13:23:26 -08001778 };
1779 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001780 RunBaseTest(&test);
1781}
1782
perkjfa10b552016-10-02 23:45:26 -07001783// This test verifies that new frame sizes reconfigures encoders even though not
1784// (yet) sending. The purpose of this is to permit encoding as quickly as
1785// possible once we start sending. Likely the frames being input are from the
1786// same source that will be sent later, which just means that we're ready
1787// earlier.
1788TEST_F(VideoSendStreamTest,
1789 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1790 class EncoderObserver : public test::FakeEncoder {
1791 public:
1792 EncoderObserver()
1793 : FakeEncoder(Clock::GetRealTimeClock()),
1794 init_encode_called_(false, false),
1795 number_of_initializations_(0),
1796 last_initialized_frame_width_(0),
1797 last_initialized_frame_height_(0) {}
1798
1799 void WaitForResolution(int width, int height) {
1800 {
1801 rtc::CritScope lock(&crit_);
1802 if (last_initialized_frame_width_ == width &&
1803 last_initialized_frame_height_ == height) {
1804 return;
1805 }
1806 }
Erik Språng08127a92016-11-16 16:41:30 +01001807 EXPECT_TRUE(
1808 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001809 {
1810 rtc::CritScope lock(&crit_);
1811 EXPECT_EQ(width, last_initialized_frame_width_);
1812 EXPECT_EQ(height, last_initialized_frame_height_);
1813 }
1814 }
1815
1816 private:
1817 int32_t InitEncode(const VideoCodec* config,
1818 int32_t number_of_cores,
1819 size_t max_payload_size) override {
1820 rtc::CritScope lock(&crit_);
1821 last_initialized_frame_width_ = config->width;
1822 last_initialized_frame_height_ = config->height;
1823 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001824 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001825 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1826 }
1827
1828 int32_t Encode(const VideoFrame& input_image,
1829 const CodecSpecificInfo* codec_specific_info,
1830 const std::vector<FrameType>* frame_types) override {
1831 ADD_FAILURE()
1832 << "Unexpected Encode call since the send stream is not started";
1833 return 0;
1834 }
1835
1836 rtc::CriticalSection crit_;
1837 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07001838 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
1839 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
1840 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07001841 };
1842
perkjfa10b552016-10-02 23:45:26 -07001843 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07001844 EncoderObserver encoder;
eladalon413ee9a2017-08-22 04:02:52 -07001845
1846 task_queue_.SendTask([this, &transport, &encoder]() {
1847 CreateSenderCall(Call::Config(event_log_.get()));
1848 CreateSendConfig(1, 0, 0, &transport);
1849 video_send_config_.encoder_settings.encoder = &encoder;
1850 CreateVideoStreams();
1851 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1852 kDefaultHeight);
1853 frame_generator_capturer_->Start();
1854 });
perkjfa10b552016-10-02 23:45:26 -07001855
1856 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07001857
1858 task_queue_.SendTask([this]() {
1859 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1860 kDefaultHeight * 2);
1861 });
1862
perkjfa10b552016-10-02 23:45:26 -07001863 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07001864
1865 task_queue_.SendTask([this]() {
1866 DestroyStreams();
1867 DestroyCalls();
1868 });
perkjfa10b552016-10-02 23:45:26 -07001869}
1870
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001871TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1872 class StartBitrateObserver : public test::FakeEncoder {
1873 public:
1874 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001875 : FakeEncoder(Clock::GetRealTimeClock()),
1876 start_bitrate_changed_(false, false),
1877 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001878 int32_t InitEncode(const VideoCodec* config,
1879 int32_t number_of_cores,
1880 size_t max_payload_size) override {
1881 rtc::CritScope lock(&crit_);
1882 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001883 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001884 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1885 }
1886
1887 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1888 rtc::CritScope lock(&crit_);
1889 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001890 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001891 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1892 }
1893
1894 int GetStartBitrateKbps() const {
1895 rtc::CritScope lock(&crit_);
1896 return start_bitrate_kbps_;
1897 }
1898
pbos14fe7082016-04-20 06:35:56 -07001899 bool WaitForStartBitrate() {
1900 return start_bitrate_changed_.Wait(
1901 VideoSendStreamTest::kDefaultTimeoutMs);
1902 }
1903
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001904 private:
pbos5ad935c2016-01-25 03:52:44 -08001905 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001906 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07001907 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001908 };
1909
philipel4fb651d2017-04-10 03:54:05 -07001910 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001911
solenberg4fbae2b2015-08-28 04:07:10 -07001912 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001913 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001914
1915 Call::Config::BitrateConfig bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07001916 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001917 sender_call_->SetBitrateConfig(bitrate_config);
1918
1919 StartBitrateObserver encoder;
stefanff483612015-12-21 03:14:00 -08001920 video_send_config_.encoder_settings.encoder = &encoder;
perkjfa10b552016-10-02 23:45:26 -07001921 // Since this test does not use a capturer, set |internal_source| = true.
1922 // Encoder configuration is otherwise updated on the next video frame.
1923 video_send_config_.encoder_settings.internal_source = true;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001924
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001925 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001926
pbos14fe7082016-04-20 06:35:56 -07001927 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07001928 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001929 encoder.GetStartBitrateKbps());
1930
perkjfa10b552016-10-02 23:45:26 -07001931 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07001932 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001933
1934 // New bitrate should be reconfigured above the previous max. As there's no
1935 // network connection this shouldn't be flaky, as no bitrate should've been
1936 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07001937 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001938 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
1939 encoder.GetStartBitrateKbps());
1940
1941 DestroyStreams();
1942}
1943
perkj57c21f92016-06-17 07:27:16 -07001944// This test that if the encoder use an internal source, VideoEncoder::SetRates
1945// will be called with zero bitrate during initialization and that
1946// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
1947// with zero bitrate.
1948TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
1949 class StartStopBitrateObserver : public test::FakeEncoder {
1950 public:
1951 StartStopBitrateObserver()
1952 : FakeEncoder(Clock::GetRealTimeClock()),
1953 encoder_init_(false, false),
Erik Språng08127a92016-11-16 16:41:30 +01001954 bitrate_changed_(false, false) {}
perkj57c21f92016-06-17 07:27:16 -07001955 int32_t InitEncode(const VideoCodec* config,
1956 int32_t number_of_cores,
1957 size_t max_payload_size) override {
1958 rtc::CritScope lock(&crit_);
perkj57c21f92016-06-17 07:27:16 -07001959 encoder_init_.Set();
1960 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1961 }
1962
Erik Språng08127a92016-11-16 16:41:30 +01001963 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
1964 uint32_t framerate) override {
perkj57c21f92016-06-17 07:27:16 -07001965 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01001966 bitrate_kbps_ = rtc::Optional<int>(bitrate.get_sum_kbps());
perkj57c21f92016-06-17 07:27:16 -07001967 bitrate_changed_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01001968 return FakeEncoder::SetRateAllocation(bitrate, framerate);
perkj57c21f92016-06-17 07:27:16 -07001969 }
1970
1971 bool WaitForEncoderInit() {
1972 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1973 }
Erik Språng08127a92016-11-16 16:41:30 +01001974
1975 bool WaitBitrateChanged(bool non_zero) {
1976 do {
1977 rtc::Optional<int> bitrate_kbps;
1978 {
1979 rtc::CritScope lock(&crit_);
1980 bitrate_kbps = bitrate_kbps_;
1981 }
1982 if (!bitrate_kbps)
1983 continue;
1984
1985 if ((non_zero && *bitrate_kbps > 0) ||
1986 (!non_zero && *bitrate_kbps == 0)) {
1987 return true;
1988 }
1989 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
1990 return false;
perkj57c21f92016-06-17 07:27:16 -07001991 }
1992
1993 private:
1994 rtc::CriticalSection crit_;
1995 rtc::Event encoder_init_;
1996 rtc::Event bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07001997 rtc::Optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
perkj57c21f92016-06-17 07:27:16 -07001998 };
1999
perkj57c21f92016-06-17 07:27:16 -07002000 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002001 StartStopBitrateObserver encoder;
perkj57c21f92016-06-17 07:27:16 -07002002
eladalon413ee9a2017-08-22 04:02:52 -07002003 task_queue_.SendTask([this, &transport, &encoder]() {
2004 CreateSenderCall(Call::Config(event_log_.get()));
2005 CreateSendConfig(1, 0, 0, &transport);
2006
2007 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
2008
2009 video_send_config_.encoder_settings.encoder = &encoder;
2010 video_send_config_.encoder_settings.internal_source = true;
2011
2012 CreateVideoStreams();
2013 });
perkj57c21f92016-06-17 07:27:16 -07002014
2015 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002016
eladalon413ee9a2017-08-22 04:02:52 -07002017 task_queue_.SendTask([this]() {
2018 video_send_stream_->Start();
2019 });
Erik Språng08127a92016-11-16 16:41:30 +01002020 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2021
eladalon413ee9a2017-08-22 04:02:52 -07002022 task_queue_.SendTask([this]() {
2023 video_send_stream_->Stop();
2024 });
Erik Språng08127a92016-11-16 16:41:30 +01002025 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2026
eladalon413ee9a2017-08-22 04:02:52 -07002027 task_queue_.SendTask([this]() {
2028 video_send_stream_->Start();
2029 });
Erik Språng08127a92016-11-16 16:41:30 +01002030 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002031
eladalon413ee9a2017-08-22 04:02:52 -07002032 task_queue_.SendTask([this]() {
2033 DestroyStreams();
2034 DestroyCalls();
2035 });
perkj57c21f92016-06-17 07:27:16 -07002036}
2037
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002038TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07002039 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002040 public:
Peter Boström5811a392015-12-10 13:02:50 +01002041 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002042
nissed30a1112016-04-18 05:15:22 -07002043 void OnFrame(const VideoFrame& video_frame) override {
2044 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01002045 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002046 }
2047
2048 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01002049 const int kWaitFrameTimeoutMs = 3000;
2050 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002051 << "Timeout while waiting for output frames.";
2052 }
2053
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002054 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002055 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002056 }
2057
2058 private:
2059 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002060 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002061
2062 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01002063 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002064 };
2065
solenberg4fbae2b2015-08-28 04:07:10 -07002066 test::NullTransport transport;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002067 FrameObserver observer;
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002068 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07002069
eladalon413ee9a2017-08-22 04:02:52 -07002070 task_queue_.SendTask([this, &transport, &observer, &input_frames]() {
2071 // Initialize send stream.
2072 CreateSenderCall(Call::Config(event_log_.get()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002073
eladalon413ee9a2017-08-22 04:02:52 -07002074 CreateSendConfig(1, 0, 0, &transport);
2075 video_send_config_.pre_encode_callback = &observer;
2076 CreateVideoStreams();
2077
2078 // Prepare five input frames. Send ordinary VideoFrame and texture frames
2079 // alternatively.
2080 int width = 168;
2081 int height = 132;
2082
2083 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2084 width, height, 1, 1, kVideoRotation_0));
2085 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2086 width, height, 2, 2, kVideoRotation_0));
2087 input_frames.push_back(CreateVideoFrame(width, height, 3));
2088 input_frames.push_back(CreateVideoFrame(width, height, 4));
2089 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2090 width, height, 5, 5, kVideoRotation_0));
2091
2092 video_send_stream_->Start();
2093 test::FrameForwarder forwarder;
2094 video_send_stream_->SetSource(
2095 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
2096 for (size_t i = 0; i < input_frames.size(); i++) {
2097 forwarder.IncomingCapturedFrame(input_frames[i]);
2098 // Wait until the output frame is received before sending the next input
2099 // frame. Or the previous input frame may be replaced without delivering.
2100 observer.WaitOutputFrame();
2101 }
2102 video_send_stream_->Stop();
2103 video_send_stream_->SetSource(
2104 nullptr, VideoSendStream::DegradationPreference::kMaintainFramerate);
2105 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002106
2107 // Test if the input and output frames are the same. render_time_ms and
2108 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002109 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002110
eladalon413ee9a2017-08-22 04:02:52 -07002111 task_queue_.SendTask([this]() {
2112 DestroyStreams();
2113 DestroyCalls();
2114 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002115}
2116
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002117void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
2118 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002119 EXPECT_EQ(frames1.size(), frames2.size());
2120 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07002121 // Compare frame buffers, since we don't care about differing timestamps.
2122 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
2123 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002124}
2125
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002126VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002127 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002128 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002129 memset(buffer.get(), data, kSizeY);
Magnus Jedvert90e31902017-06-07 11:32:50 +02002130 VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002131 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002132 // Use data as a ms timestamp.
2133 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002134 return frame;
2135}
2136
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002137TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
2138 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2139 public:
eladalon413ee9a2017-08-22 04:02:52 -07002140 explicit EncoderStateObserver(
2141 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002142 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002143 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002144 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002145 initialized_(false),
2146 callback_registered_(false),
2147 num_releases_(0),
2148 released_(false) {}
2149
2150 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002151 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002152 return released_;
2153 }
2154
2155 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002156 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002157 return initialized_ && callback_registered_;
2158 }
2159
2160 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002161 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002162 return num_releases_;
2163 }
2164
2165 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002166 int32_t InitEncode(const VideoCodec* codecSettings,
2167 int32_t numberOfCores,
2168 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002169 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002170 EXPECT_FALSE(initialized_);
2171 initialized_ = true;
2172 released_ = false;
2173 return 0;
2174 }
2175
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002176 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002177 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002178 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002179 EXPECT_TRUE(IsReadyForEncode());
2180
Peter Boström5811a392015-12-10 13:02:50 +01002181 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002182 return 0;
2183 }
2184
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002185 int32_t RegisterEncodeCompleteCallback(
2186 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002187 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002188 EXPECT_TRUE(initialized_);
2189 callback_registered_ = true;
2190 return 0;
2191 }
2192
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002193 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002194 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002195 EXPECT_TRUE(IsReadyForEncode());
2196 EXPECT_FALSE(released_);
2197 initialized_ = false;
2198 callback_registered_ = false;
2199 released_ = true;
2200 ++num_releases_;
2201 return 0;
2202 }
2203
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002204 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002205 EXPECT_TRUE(IsReadyForEncode());
2206 return 0;
2207 }
2208
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002209 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002210 EXPECT_TRUE(IsReadyForEncode());
2211 return 0;
2212 }
2213
stefanff483612015-12-21 03:14:00 -08002214 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002215 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002216 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002217 stream_ = send_stream;
2218 }
2219
stefanff483612015-12-21 03:14:00 -08002220 void ModifyVideoConfigs(
2221 VideoSendStream::Config* send_config,
2222 std::vector<VideoReceiveStream::Config>* receive_configs,
2223 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002224 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07002225 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002226 }
2227
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002228 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002229 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002230
2231 task_queue_->SendTask([this]() {
2232 EXPECT_EQ(0u, num_releases());
2233 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2234 EXPECT_EQ(0u, num_releases());
2235 stream_->Stop();
2236 // Encoder should not be released before destroying the VideoSendStream.
2237 EXPECT_FALSE(IsReleased());
2238 EXPECT_TRUE(IsReadyForEncode());
2239 stream_->Start();
2240 });
2241
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002242 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002243 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002244 }
2245
eladalon413ee9a2017-08-22 04:02:52 -07002246 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002247 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002248 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002249 bool initialized_ RTC_GUARDED_BY(crit_);
2250 bool callback_registered_ RTC_GUARDED_BY(crit_);
2251 size_t num_releases_ RTC_GUARDED_BY(crit_);
2252 bool released_ RTC_GUARDED_BY(crit_);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002253 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002254 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002255
stefane74eef12016-01-08 06:47:13 -08002256 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002257
2258 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002259 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002260}
2261
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002262TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2263 class VideoCodecConfigObserver : public test::SendTest,
2264 public test::FakeEncoder {
2265 public:
2266 VideoCodecConfigObserver()
2267 : SendTest(kDefaultTimeoutMs),
2268 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002269 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002270 num_initializations_(0),
2271 stream_(nullptr) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002272
2273 private:
stefanff483612015-12-21 03:14:00 -08002274 void ModifyVideoConfigs(
2275 VideoSendStream::Config* send_config,
2276 std::vector<VideoReceiveStream::Config>* receive_configs,
2277 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002278 send_config->encoder_settings.encoder = this;
sprangf24a0642017-02-28 13:23:26 -08002279 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002280 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002281 }
2282
stefanff483612015-12-21 03:14:00 -08002283 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002284 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002285 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002286 stream_ = send_stream;
2287 }
2288
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002289 int32_t InitEncode(const VideoCodec* config,
2290 int32_t number_of_cores,
2291 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002292 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002293 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002294 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002295 } else {
2296 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002297 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002298 }
2299 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002300 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002301 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2302 }
2303
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002304 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002305 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002306 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002307
sprangf24a0642017-02-28 13:23:26 -08002308 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002309 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002310 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002311 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002312 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2313 "new encoder settings.";
2314 }
2315
sprangf24a0642017-02-28 13:23:26 -08002316 const uint32_t kFirstMaxBitrateBps = 1000000;
2317 const uint32_t kSecondMaxBitrateBps = 2000000;
2318
pbos14fe7082016-04-20 06:35:56 -07002319 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002320 size_t num_initializations_;
2321 VideoSendStream* stream_;
2322 VideoEncoderConfig encoder_config_;
2323 } test;
2324
stefane74eef12016-01-08 06:47:13 -08002325 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002326}
2327
Peter Boström53eda3d2015-03-27 15:53:18 +01002328static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
2329template <typename T>
2330class VideoCodecConfigObserver : public test::SendTest,
2331 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002332 public:
2333 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2334 const char* codec_name)
2335 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2336 FakeEncoder(Clock::GetRealTimeClock()),
2337 video_codec_type_(video_codec_type),
2338 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002339 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002340 num_initializations_(0),
2341 stream_(nullptr) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002342 memset(&encoder_settings_, 0, sizeof(encoder_settings_));
2343 }
2344
2345 private:
perkjfa10b552016-10-02 23:45:26 -07002346 class VideoStreamFactory
2347 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2348 public:
2349 VideoStreamFactory() {}
2350
2351 private:
2352 std::vector<VideoStream> CreateEncoderStreams(
2353 int width,
2354 int height,
2355 const VideoEncoderConfig& encoder_config) override {
2356 std::vector<VideoStream> streams =
2357 test::CreateVideoStreams(width, height, encoder_config);
2358 for (size_t i = 0; i < streams.size(); ++i) {
2359 streams[i].temporal_layer_thresholds_bps.resize(
2360 kVideoCodecConfigObserverNumberOfTemporalLayers - 1);
2361 }
2362 return streams;
2363 }
2364 };
2365
stefanff483612015-12-21 03:14:00 -08002366 void ModifyVideoConfigs(
2367 VideoSendStream::Config* send_config,
2368 std::vector<VideoReceiveStream::Config>* receive_configs,
2369 VideoEncoderConfig* encoder_config) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002370 send_config->encoder_settings.encoder = this;
2371 send_config->encoder_settings.payload_name = codec_name_;
2372
kthelgason29a44e32016-09-27 03:52:02 -07002373 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002374 encoder_config->video_stream_factory =
2375 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002376 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002377 }
2378
stefanff483612015-12-21 03:14:00 -08002379 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002380 VideoSendStream* send_stream,
2381 const std::vector<VideoReceiveStream*>& receive_streams) override {
2382 stream_ = send_stream;
2383 }
2384
2385 int32_t InitEncode(const VideoCodec* config,
2386 int32_t number_of_cores,
2387 size_t max_payload_size) override {
2388 EXPECT_EQ(video_codec_type_, config->codecType);
2389 VerifyCodecSpecifics(*config);
2390 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002391 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002392 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2393 }
2394
2395 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002396 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2397 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002398
2399 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002400 EXPECT_TRUE(
2401 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002402 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002403
2404 encoder_settings_.frameDroppingOn = true;
kthelgason29a44e32016-09-27 03:52:02 -07002405 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002406 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002407 ASSERT_TRUE(
2408 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002409 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002410 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2411 "new encoder settings.";
2412 }
2413
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002414 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002415 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002416 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002417 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2418 return 0;
2419 }
2420
2421 T encoder_settings_;
2422 const VideoCodecType video_codec_type_;
2423 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002424 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002425 size_t num_initializations_;
2426 VideoSendStream* stream_;
2427 VideoEncoderConfig encoder_config_;
2428};
2429
2430template <>
2431void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2432 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002433 EXPECT_EQ(
2434 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002435}
kthelgason29a44e32016-09-27 03:52:02 -07002436
2437template <>
2438rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2439VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2440 return new rtc::RefCountedObject<
2441 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2442}
2443
Peter Boström53eda3d2015-03-27 15:53:18 +01002444template <>
2445void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2446 const VideoCodec& config) const {
2447 // Check that the number of temporal layers has propagated properly to
2448 // VideoCodec.
2449 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002450 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002451
2452 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2453 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2454 config.simulcastStream[i].numberOfTemporalLayers);
2455 }
2456
2457 // Set expected temporal layers as they should have been set when
Erik Språng08127a92016-11-16 16:41:30 +01002458 // reconfiguring the encoder and not match the set config. Also copy the
mflodmancc3d4422017-08-03 08:27:51 -07002459 // TemporalLayersFactory pointer that has been injected by VideoStreamEncoder.
Peter Boström53eda3d2015-03-27 15:53:18 +01002460 VideoCodecVP8 encoder_settings = encoder_settings_;
2461 encoder_settings.numberOfTemporalLayers =
2462 kVideoCodecConfigObserverNumberOfTemporalLayers;
Erik Språng08127a92016-11-16 16:41:30 +01002463 encoder_settings.tl_factory = config.VP8().tl_factory;
hta257dc392016-10-25 09:05:06 -07002464 EXPECT_EQ(
2465 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002466}
kthelgason29a44e32016-09-27 03:52:02 -07002467
2468template <>
2469rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2470VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2471 return new rtc::RefCountedObject<
2472 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2473}
2474
Peter Boström53eda3d2015-03-27 15:53:18 +01002475template <>
2476void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2477 const VideoCodec& config) const {
2478 // Check that the number of temporal layers has propagated properly to
2479 // VideoCodec.
2480 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002481 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002482
2483 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2484 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2485 config.simulcastStream[i].numberOfTemporalLayers);
2486 }
2487
2488 // Set expected temporal layers as they should have been set when
2489 // reconfiguring the encoder and not match the set config.
2490 VideoCodecVP9 encoder_settings = encoder_settings_;
2491 encoder_settings.numberOfTemporalLayers =
2492 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002493 EXPECT_EQ(
2494 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002495}
2496
kthelgason29a44e32016-09-27 03:52:02 -07002497template <>
2498rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2499VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2500 return new rtc::RefCountedObject<
2501 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2502}
2503
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002504TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002505 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002506 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002507}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002508
Peter Boström53eda3d2015-03-27 15:53:18 +01002509TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2510 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002511 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002512}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002513
Peter Boström53eda3d2015-03-27 15:53:18 +01002514TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2515 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002516 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002517}
2518
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002519TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002520 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002521 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002522 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2523 rtp_packets_sent_(0),
2524 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002525
2526 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002527 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002528 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002529 RTPHeader header;
2530 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002531 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002532 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2533 return SEND_PACKET;
2534 }
2535
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002536 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002537 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002538 test::RtcpPacketParser parser;
2539 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002540
danilchap3dc929e2016-11-02 08:21:59 -07002541 if (parser.sender_report()->num_packets() > 0) {
2542 // Only compare sent media bytes if SenderPacketCount matches the
2543 // number of sent rtp packets (a new rtp packet could be sent before
2544 // the rtcp packet).
2545 if (parser.sender_report()->sender_octet_count() > 0 &&
2546 parser.sender_report()->sender_packet_count() ==
2547 rtp_packets_sent_) {
2548 EXPECT_EQ(media_bytes_sent_,
2549 parser.sender_report()->sender_octet_count());
2550 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002551 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002552 }
2553
2554 return SEND_PACKET;
2555 }
2556
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002557 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002558 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002559 }
2560
stefan4b569042015-11-11 06:39:57 -08002561 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002562 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2563 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002564 } test;
2565
stefane74eef12016-01-08 06:47:13 -08002566 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002567}
2568
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002569TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
2570 static const int kScreencastTargetBitrateKbps = 200;
perkjfa10b552016-10-02 23:45:26 -07002571
2572 class VideoStreamFactory
2573 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2574 public:
2575 VideoStreamFactory() {}
2576
2577 private:
2578 std::vector<VideoStream> CreateEncoderStreams(
2579 int width,
2580 int height,
2581 const VideoEncoderConfig& encoder_config) override {
2582 std::vector<VideoStream> streams =
2583 test::CreateVideoStreams(width, height, encoder_config);
2584 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
2585 streams[0].temporal_layer_thresholds_bps.push_back(
2586 kScreencastTargetBitrateKbps * 1000);
2587 return streams;
2588 }
2589 };
2590
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002591 class ScreencastTargetBitrateTest : public test::SendTest,
2592 public test::FakeEncoder {
2593 public:
2594 ScreencastTargetBitrateTest()
2595 : SendTest(kDefaultTimeoutMs),
2596 test::FakeEncoder(Clock::GetRealTimeClock()) {}
2597
2598 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002599 int32_t InitEncode(const VideoCodec* config,
2600 int32_t number_of_cores,
2601 size_t max_payload_size) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002602 EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps),
2603 config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002604 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002605 return test::FakeEncoder::InitEncode(
2606 config, number_of_cores, max_payload_size);
2607 }
stefanff483612015-12-21 03:14:00 -08002608 void ModifyVideoConfigs(
2609 VideoSendStream::Config* send_config,
2610 std::vector<VideoReceiveStream::Config>* receive_configs,
2611 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002612 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002613 EXPECT_EQ(1u, encoder_config->number_of_streams);
2614 encoder_config->video_stream_factory =
2615 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002616 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002617 }
2618
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002619 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002620 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002621 << "Timed out while waiting for the encoder to be initialized.";
2622 }
2623 } test;
2624
stefane74eef12016-01-08 06:47:13 -08002625 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002626}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002627
philipelc6957c72016-04-28 15:52:49 +02002628TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002629 // These are chosen to be "kind of odd" to not be accidentally checked against
2630 // default values.
2631 static const int kMinBitrateKbps = 137;
2632 static const int kStartBitrateKbps = 345;
2633 static const int kLowerMaxBitrateKbps = 312;
2634 static const int kMaxBitrateKbps = 413;
2635 static const int kIncreasedStartBitrateKbps = 451;
2636 static const int kIncreasedMaxBitrateKbps = 597;
2637 class EncoderBitrateThresholdObserver : public test::SendTest,
2638 public test::FakeEncoder {
2639 public:
eladalon413ee9a2017-08-22 04:02:52 -07002640 explicit EncoderBitrateThresholdObserver(
2641 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002642 : SendTest(kDefaultTimeoutMs),
2643 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002644 task_queue_(task_queue),
pbos14fe7082016-04-20 06:35:56 -07002645 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002646 bitrate_changed_event_(false, false),
2647 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002648 num_initializations_(0),
2649 call_(nullptr),
2650 send_stream_(nullptr) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002651
2652 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002653 int32_t InitEncode(const VideoCodec* codecSettings,
2654 int32_t numberOfCores,
2655 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002656 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2657 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002658 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002659 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2660 codecSettings->minBitrate);
2661 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2662 codecSettings->startBitrate);
2663 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2664 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002665 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002666 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002667 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2668 codecSettings->maxBitrate);
2669 // The start bitrate should be kept (-1) and capped to the max bitrate.
2670 // Since this is not an end-to-end call no receiver should have been
2671 // returning a REMB that could lower this estimate.
2672 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002673 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002674 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2675 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002676 // The start bitrate will be whatever the rate BitRateController
2677 // has currently configured but in the span of the set max and min
2678 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002679 }
2680 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002681 init_encode_event_.Set();
2682
pbos@webrtc.org00873182014-11-25 14:03:34 +00002683 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2684 maxPayloadSize);
2685 }
2686
Erik Språng08127a92016-11-16 16:41:30 +01002687 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
2688 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002689 {
2690 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002691 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2692 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002693 }
Erik Språng08127a92016-11-16 16:41:30 +01002694 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002695 }
2696 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002697 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002698 }
2699
2700 void WaitForSetRates(uint32_t expected_bitrate) {
2701 EXPECT_TRUE(
2702 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2703 << "Timed out while waiting encoder rate to be set.";
2704 rtc::CritScope lock(&crit_);
2705 EXPECT_EQ(expected_bitrate, target_bitrate_);
2706 }
2707
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002708 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07002709 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01002710 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2711 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2712 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002713 return config;
2714 }
2715
perkjfa10b552016-10-02 23:45:26 -07002716 class VideoStreamFactory
2717 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2718 public:
2719 explicit VideoStreamFactory(int min_bitrate_bps)
2720 : min_bitrate_bps_(min_bitrate_bps) {}
2721
2722 private:
2723 std::vector<VideoStream> CreateEncoderStreams(
2724 int width,
2725 int height,
2726 const VideoEncoderConfig& encoder_config) override {
2727 std::vector<VideoStream> streams =
2728 test::CreateVideoStreams(width, height, encoder_config);
2729 streams[0].min_bitrate_bps = min_bitrate_bps_;
2730 return streams;
2731 }
2732
2733 const int min_bitrate_bps_;
2734 };
2735
stefanff483612015-12-21 03:14:00 -08002736 void ModifyVideoConfigs(
2737 VideoSendStream::Config* send_config,
2738 std::vector<VideoReceiveStream::Config>* receive_configs,
2739 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002740 send_config->encoder_settings.encoder = this;
2741 // Set bitrates lower/higher than min/max to make sure they are properly
2742 // capped.
perkjfa10b552016-10-02 23:45:26 -07002743 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2744 // Create a new StreamFactory to be able to set
2745 // |VideoStream.min_bitrate_bps|.
2746 encoder_config->video_stream_factory =
2747 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002748 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002749 }
2750
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002751 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002752 call_ = sender_call;
2753 }
2754
stefanff483612015-12-21 03:14:00 -08002755 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002756 VideoSendStream* send_stream,
2757 const std::vector<VideoReceiveStream*>& receive_streams) override {
2758 send_stream_ = send_stream;
2759 }
2760
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002761 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002762 ASSERT_TRUE(
2763 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002764 << "Timed out while waiting for encoder to be configured.";
2765 WaitForSetRates(kStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002766 Call::Config::BitrateConfig bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002767 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2768 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002769 task_queue_->SendTask([this, &bitrate_config]() {
2770 call_->SetBitrateConfig(bitrate_config);
2771 });
perkj26091b12016-09-01 01:17:40 -07002772 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2773 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002774 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002775 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002776 ASSERT_TRUE(
2777 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002778 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002779 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002780 WaitForSetRates(kLowerMaxBitrateKbps);
2781
2782 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2783 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2784 ASSERT_TRUE(
2785 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002786 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002787 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002788 // Expected target bitrate is the start bitrate set in the call to
2789 // call_->SetBitrateConfig.
2790 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002791 }
2792
eladalon413ee9a2017-08-22 04:02:52 -07002793 test::SingleThreadedTaskQueueForTesting* const task_queue_;
pbos14fe7082016-04-20 06:35:56 -07002794 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002795 rtc::Event bitrate_changed_event_;
2796 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002797 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002798
pbos@webrtc.org00873182014-11-25 14:03:34 +00002799 int num_initializations_;
2800 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002801 webrtc::VideoSendStream* send_stream_;
2802 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002803 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002804
stefane74eef12016-01-08 06:47:13 -08002805 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002806}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002807
2808TEST_F(VideoSendStreamTest, ReportsSentResolution) {
2809 static const size_t kNumStreams = 3;
2810 // Unusual resolutions to make sure that they are the ones being reported.
2811 static const struct {
2812 int width;
2813 int height;
2814 } kEncodedResolution[kNumStreams] = {
2815 {241, 181}, {300, 121}, {121, 221}};
2816 class ScreencastTargetBitrateTest : public test::SendTest,
2817 public test::FakeEncoder {
2818 public:
2819 ScreencastTargetBitrateTest()
2820 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002821 test::FakeEncoder(Clock::GetRealTimeClock()),
2822 send_stream_(nullptr) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002823
2824 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002825 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002826 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002827 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002828 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002829 specifics.codecType = kVideoCodecGeneric;
2830
2831 uint8_t buffer[16] = {0};
2832 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
2833 encoded._timeStamp = input_image.timestamp();
2834 encoded.capture_time_ms_ = input_image.render_time_ms();
2835
2836 for (size_t i = 0; i < kNumStreams; ++i) {
2837 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
2838 encoded._frameType = (*frame_types)[i];
2839 encoded._encodedWidth = kEncodedResolution[i].width;
2840 encoded._encodedHeight = kEncodedResolution[i].height;
brandtre78d2662017-01-16 05:57:16 -08002841 EncodedImageCallback* callback;
2842 {
2843 rtc::CritScope cs(&crit_sect_);
2844 callback = callback_;
2845 }
2846 RTC_DCHECK(callback);
2847 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07002848 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002849 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07002850 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002851 }
2852
Peter Boström5811a392015-12-10 13:02:50 +01002853 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002854 return 0;
2855 }
stefanff483612015-12-21 03:14:00 -08002856 void ModifyVideoConfigs(
2857 VideoSendStream::Config* send_config,
2858 std::vector<VideoReceiveStream::Config>* receive_configs,
2859 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002860 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002861 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002862 }
2863
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002864 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002865
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002866 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002867 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002868 << "Timed out while waiting for the encoder to send one frame.";
2869 VideoSendStream::Stats stats = send_stream_->GetStats();
2870
2871 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002872 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002873 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002874 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002875 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002876 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002877 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002878 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
2879 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002880 }
2881 }
2882
stefanff483612015-12-21 03:14:00 -08002883 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002884 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002885 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002886 send_stream_ = send_stream;
2887 }
2888
2889 VideoSendStream* send_stream_;
2890 } test;
2891
stefane74eef12016-01-08 06:47:13 -08002892 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002893}
philipel0f9af012015-09-01 07:01:51 -07002894
Peter Boström12996152016-05-14 02:03:18 +02002895#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01002896class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07002897 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01002898 Vp9HeaderObserver()
2899 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
philipel7fabd462015-09-03 04:42:32 -07002900 vp9_encoder_(VP9Encoder::Create()),
Åsa Perssonff24c042015-12-04 10:58:08 +01002901 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
2902 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07002903 frames_sent_(0),
2904 expected_width_(0),
2905 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07002906
stefanff483612015-12-21 03:14:00 -08002907 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07002908 VideoSendStream::Config* send_config,
2909 std::vector<VideoReceiveStream::Config>* receive_configs,
2910 VideoEncoderConfig* encoder_config) {}
2911
Åsa Perssonff24c042015-12-04 10:58:08 +01002912 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07002913
2914 private:
minyue20c84cc2017-04-10 16:57:57 -07002915 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07002916
perkjfa10b552016-10-02 23:45:26 -07002917 class VideoStreamFactory
2918 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2919 public:
2920 explicit VideoStreamFactory(size_t number_of_temporal_layers)
2921 : number_of_temporal_layers_(number_of_temporal_layers) {}
2922
2923 private:
2924 std::vector<VideoStream> CreateEncoderStreams(
2925 int width,
2926 int height,
2927 const VideoEncoderConfig& encoder_config) override {
2928 std::vector<VideoStream> streams =
2929 test::CreateVideoStreams(width, height, encoder_config);
2930 streams[0].temporal_layer_thresholds_bps.resize(
2931 number_of_temporal_layers_ - 1);
2932 return streams;
2933 }
2934
2935 const size_t number_of_temporal_layers_;
2936 };
2937
stefanff483612015-12-21 03:14:00 -08002938 void ModifyVideoConfigs(
2939 VideoSendStream::Config* send_config,
2940 std::vector<VideoReceiveStream::Config>* receive_configs,
2941 VideoEncoderConfig* encoder_config) override {
philipel7fabd462015-09-03 04:42:32 -07002942 send_config->encoder_settings.encoder = vp9_encoder_.get();
philipel0f9af012015-09-01 07:01:51 -07002943 send_config->encoder_settings.payload_name = "VP9";
2944 send_config->encoder_settings.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08002945 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07002946 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
2947 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07002948 EXPECT_EQ(1u, encoder_config->number_of_streams);
2949 encoder_config->video_stream_factory =
2950 new rtc::RefCountedObject<VideoStreamFactory>(
2951 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07002952 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07002953 }
2954
perkjfa10b552016-10-02 23:45:26 -07002955 void ModifyVideoCaptureStartResolution(int* width,
2956 int* height,
2957 int* frame_rate) override {
2958 expected_width_ = *width;
2959 expected_height_ = *height;
2960 }
2961
philipel0f9af012015-09-01 07:01:51 -07002962 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002963 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
2964 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002965 }
2966
2967 Action OnSendRtp(const uint8_t* packet, size_t length) override {
2968 RTPHeader header;
2969 EXPECT_TRUE(parser_->Parse(packet, length, &header));
2970
Åsa Perssonff24c042015-12-04 10:58:08 +01002971 EXPECT_EQ(kVp9PayloadType, header.payloadType);
2972 const uint8_t* payload = packet + header.headerLength;
2973 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07002974
Åsa Perssonff24c042015-12-04 10:58:08 +01002975 bool new_packet = packets_sent_ == 0 ||
2976 IsNewerSequenceNumber(header.sequenceNumber,
2977 last_header_.sequenceNumber);
2978 if (payload_length > 0 && new_packet) {
2979 RtpDepacketizer::ParsedPayload parsed;
2980 RtpDepacketizerVp9 depacketizer;
2981 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
2982 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
2983 // Verify common fields for all configurations.
2984 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
2985 CompareConsecutiveFrames(header, parsed.type.Video);
2986 // Verify configuration specific settings.
2987 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07002988
Åsa Perssonff24c042015-12-04 10:58:08 +01002989 ++packets_sent_;
2990 if (header.markerBit) {
2991 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002992 }
Åsa Perssonff24c042015-12-04 10:58:08 +01002993 last_header_ = header;
2994 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07002995 }
philipel0f9af012015-09-01 07:01:51 -07002996 return SEND_PACKET;
2997 }
2998
philipel7fabd462015-09-03 04:42:32 -07002999 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01003000 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
3001 if (last_vp9_.picture_id > vp9.picture_id) {
3002 return vp9.picture_id == 0; // Wrap.
3003 } else {
3004 return vp9.picture_id == last_vp9_.picture_id + 1;
3005 }
3006 }
3007
3008 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003009 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3010 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3011 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3012 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3013 vp9.spatial_idx);
3014 }
3015
3016 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3017 uint8_t num_layers) const {
3018 switch (num_layers) {
3019 case 0:
3020 VerifyTemporalLayerStructure0(vp9);
3021 break;
3022 case 1:
3023 VerifyTemporalLayerStructure1(vp9);
3024 break;
3025 case 2:
3026 VerifyTemporalLayerStructure2(vp9);
3027 break;
3028 case 3:
3029 VerifyTemporalLayerStructure3(vp9);
3030 break;
3031 default:
3032 RTC_NOTREACHED();
3033 }
3034 }
3035
3036 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3037 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3038 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3039 EXPECT_FALSE(vp9.temporal_up_switch);
3040 }
3041
3042 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3043 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3044 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3045 EXPECT_FALSE(vp9.temporal_up_switch);
3046 }
3047
3048 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3049 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3050 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3051 EXPECT_LE(vp9.temporal_idx, 1);
3052 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3053 if (IsNewPictureId(vp9)) {
3054 uint8_t expected_tid =
3055 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3056 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3057 }
3058 }
3059
3060 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3061 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3062 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3063 EXPECT_LE(vp9.temporal_idx, 2);
3064 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3065 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3066 switch (vp9.temporal_idx) {
3067 case 0:
3068 EXPECT_EQ(2, last_vp9_.temporal_idx);
3069 EXPECT_FALSE(vp9.temporal_up_switch);
3070 break;
3071 case 1:
3072 EXPECT_EQ(2, last_vp9_.temporal_idx);
3073 EXPECT_TRUE(vp9.temporal_up_switch);
3074 break;
3075 case 2:
3076 EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
3077 break;
3078 }
3079 }
3080 }
3081
3082 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3083 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3084 return;
3085
3086 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3087 if (vp9.temporal_idx == 0)
3088 ++expected_tl0_idx;
3089 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3090 }
3091
3092 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3093 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3094 }
3095
3096 // Flexible mode (F=1): Non-flexible mode (F=0):
3097 //
3098 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3099 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3100 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3101 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3102 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3103 // M: | EXTENDED PID | M: | EXTENDED PID |
3104 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3105 // L: | T |U| S |D| L: | T |U| S |D|
3106 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3107 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3108 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3109 // X: |EXTENDED P_DIFF| V: | SS .. |
3110 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3111 // V: | SS .. |
3112 // +-+-+-+-+-+-+-+-+
3113 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3114 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3115 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3116 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003117
3118 if (vp9_settings_.numberOfSpatialLayers > 1) {
3119 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3120 } else if (vp9_settings_.numberOfTemporalLayers > 1) {
3121 EXPECT_EQ(vp9.spatial_idx, 0);
3122 } else {
3123 EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
3124 }
3125
3126 if (vp9_settings_.numberOfTemporalLayers > 1) {
3127 EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
3128 } else if (vp9_settings_.numberOfSpatialLayers > 1) {
3129 EXPECT_EQ(vp9.temporal_idx, 0);
3130 } else {
3131 EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
3132 }
3133
Åsa Perssonff24c042015-12-04 10:58:08 +01003134 if (vp9.ss_data_available) // V
3135 VerifySsData(vp9);
3136
3137 if (frames_sent_ == 0)
3138 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3139
3140 if (!vp9.inter_pic_predicted) {
3141 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3142 EXPECT_FALSE(vp9.temporal_up_switch);
3143 }
3144 }
3145
3146 // Scalability structure (SS).
3147 //
3148 // +-+-+-+-+-+-+-+-+
3149 // V: | N_S |Y|G|-|-|-|
3150 // +-+-+-+-+-+-+-+-+
3151 // Y: | WIDTH | N_S + 1 times
3152 // +-+-+-+-+-+-+-+-+
3153 // | HEIGHT |
3154 // +-+-+-+-+-+-+-+-+
3155 // G: | N_G |
3156 // +-+-+-+-+-+-+-+-+
3157 // N_G: | T |U| R |-|-| N_G times
3158 // +-+-+-+-+-+-+-+-+
3159 // | P_DIFF | R times
3160 // +-+-+-+-+-+-+-+-+
3161 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3162 EXPECT_TRUE(vp9.ss_data_available); // V
3163 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3164 vp9.num_spatial_layers);
3165 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003166 int expected_width = expected_width_;
3167 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003168 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003169 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3170 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3171 expected_width /= 2;
3172 expected_height /= 2;
3173 }
3174 }
3175
3176 void CompareConsecutiveFrames(const RTPHeader& header,
3177 const RTPVideoHeader& video) const {
3178 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
3179
3180 bool new_frame = packets_sent_ == 0 ||
3181 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003182 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003183 if (!new_frame) {
3184 EXPECT_FALSE(last_header_.markerBit);
3185 EXPECT_EQ(last_header_.timestamp, header.timestamp);
3186 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
3187 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
3188 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
3189 VerifySpatialIdxWithinFrame(vp9);
3190 return;
3191 }
3192 // New frame.
3193 EXPECT_TRUE(vp9.beginning_of_frame);
3194
3195 // Compare with last packet in previous frame.
3196 if (frames_sent_ == 0)
3197 return;
3198 EXPECT_TRUE(last_vp9_.end_of_frame);
3199 EXPECT_TRUE(last_header_.markerBit);
3200 EXPECT_TRUE(ContinuousPictureId(vp9));
3201 VerifyTl0Idx(vp9);
3202 }
3203
kwiberg27f982b2016-03-01 11:52:33 -08003204 std::unique_ptr<VP9Encoder> vp9_encoder_;
philipel0f9af012015-09-01 07:01:51 -07003205 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003206 webrtc::VideoEncoderConfig encoder_config_;
3207 RTPHeader last_header_;
3208 RTPVideoHeaderVP9 last_vp9_;
3209 size_t packets_sent_;
3210 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003211 int expected_width_;
3212 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003213};
3214
Åsa Perssonff24c042015-12-04 10:58:08 +01003215TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
3216 const uint8_t kNumTemporalLayers = 1;
3217 const uint8_t kNumSpatialLayers = 1;
3218 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3219}
3220
3221TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
3222 const uint8_t kNumTemporalLayers = 2;
3223 const uint8_t kNumSpatialLayers = 1;
3224 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3225}
3226
3227TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
3228 const uint8_t kNumTemporalLayers = 3;
3229 const uint8_t kNumSpatialLayers = 1;
3230 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3231}
3232
3233TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
3234 const uint8_t kNumTemporalLayers = 1;
3235 const uint8_t kNumSpatialLayers = 2;
3236 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3237}
3238
3239TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3240 const uint8_t kNumTemporalLayers = 2;
3241 const uint8_t kNumSpatialLayers = 2;
3242 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3243}
3244
3245TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3246 const uint8_t kNumTemporalLayers = 3;
3247 const uint8_t kNumSpatialLayers = 2;
3248 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3249}
3250
3251void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3252 uint8_t num_spatial_layers) {
3253 static const size_t kNumFramesToSend = 100;
3254 // Set to < kNumFramesToSend and coprime to length of temporal layer
3255 // structures to verify temporal id reset on key frame.
3256 static const int kKeyFrameInterval = 31;
3257 class NonFlexibleMode : public Vp9HeaderObserver {
3258 public:
3259 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3260 : num_temporal_layers_(num_temporal_layers),
3261 num_spatial_layers_(num_spatial_layers),
3262 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
stefanff483612015-12-21 03:14:00 -08003263 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003264 VideoSendStream::Config* send_config,
3265 std::vector<VideoReceiveStream::Config>* receive_configs,
3266 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003267 vp9_settings_.flexibleMode = false;
3268 vp9_settings_.frameDroppingOn = false;
3269 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3270 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3271 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003272 }
3273
Åsa Perssonff24c042015-12-04 10:58:08 +01003274 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003275 bool ss_data_expected =
3276 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3277 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003278 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003279 if (num_spatial_layers_ > 1) {
3280 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3281 } else {
3282 EXPECT_FALSE(vp9.inter_layer_predicted);
3283 }
3284
asapersson38bb8ad2015-12-14 01:41:19 -08003285 EXPECT_EQ(!vp9.inter_pic_predicted,
3286 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003287
3288 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003289 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3290 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3291 } else {
3292 EXPECT_EQ(0, vp9.spatial_idx);
3293 }
3294 if (num_spatial_layers_ > 1)
3295 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003296 }
3297
3298 VerifyFixedTemporalLayerStructure(vp9,
3299 l_field_ ? num_temporal_layers_ : 0);
3300
3301 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003302 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003303 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003304 const uint8_t num_temporal_layers_;
3305 const uint8_t num_spatial_layers_;
3306 const bool l_field_;
3307 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003308
stefane74eef12016-01-08 06:47:13 -08003309 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003310}
3311
asaperssond9f641e2016-01-21 01:11:35 -08003312TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3313 static const size_t kNumFramesToSend = 50;
3314 static const int kWidth = 4;
3315 static const int kHeight = 4;
3316 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3317 void ModifyVideoConfigsHook(
3318 VideoSendStream::Config* send_config,
3319 std::vector<VideoReceiveStream::Config>* receive_configs,
3320 VideoEncoderConfig* encoder_config) override {
3321 vp9_settings_.flexibleMode = false;
3322 vp9_settings_.numberOfTemporalLayers = 1;
3323 vp9_settings_.numberOfSpatialLayers = 1;
3324
perkjfa10b552016-10-02 23:45:26 -07003325 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003326 }
3327
3328 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3329 if (frames_sent_ > kNumFramesToSend)
3330 observation_complete_.Set();
3331 }
perkjfa10b552016-10-02 23:45:26 -07003332
3333 void ModifyVideoCaptureStartResolution(int* width,
3334 int* height,
3335 int* frame_rate) override {
3336 expected_width_ = kWidth;
3337 expected_height_ = kHeight;
3338 *width = kWidth;
3339 *height = kHeight;
3340 }
asaperssond9f641e2016-01-21 01:11:35 -08003341 } test;
3342
3343 RunBaseTest(&test);
3344}
3345
kjellanderf9e2a362017-03-24 12:17:33 -07003346#if defined(WEBRTC_ANDROID)
3347// Crashes on Android; bugs.webrtc.org/7401
3348#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3349#else
3350#define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
3351#endif
3352TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003353 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003354 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003355 VideoSendStream::Config* send_config,
3356 std::vector<VideoReceiveStream::Config>* receive_configs,
3357 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003358 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003359 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003360 vp9_settings_.numberOfTemporalLayers = 1;
3361 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003362 }
3363
Åsa Perssonff24c042015-12-04 10:58:08 +01003364 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3365 EXPECT_TRUE(vp9_header.flexible_mode);
3366 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3367 if (vp9_header.inter_pic_predicted) {
3368 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003369 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003370 }
3371 }
3372 } test;
3373
stefane74eef12016-01-08 06:47:13 -08003374 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003375}
Peter Boström12996152016-05-14 02:03:18 +02003376#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003377
perkj803d97f2016-11-01 11:45:46 -07003378void VideoSendStreamTest::TestRequestSourceRotateVideo(
3379 bool support_orientation_ext) {
philipel4fb651d2017-04-10 03:54:05 -07003380 CreateSenderCall(Call::Config(event_log_.get()));
perkj803d97f2016-11-01 11:45:46 -07003381
3382 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003383 CreateSendConfig(1, 0, 0, &transport);
perkj803d97f2016-11-01 11:45:46 -07003384 video_send_config_.rtp.extensions.clear();
3385 if (support_orientation_ext) {
3386 video_send_config_.rtp.extensions.push_back(
3387 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3388 }
3389
3390 CreateVideoStreams();
3391 test::FrameForwarder forwarder;
3392 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07003393 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
perkj803d97f2016-11-01 11:45:46 -07003394
3395 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3396 support_orientation_ext);
3397
3398 DestroyStreams();
3399}
3400
3401TEST_F(VideoSendStreamTest,
3402 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3403 TestRequestSourceRotateVideo(false);
3404}
3405
3406TEST_F(VideoSendStreamTest,
3407 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3408 TestRequestSourceRotateVideo(true);
3409}
3410
michaelta3328772016-11-29 09:25:03 -08003411// This test verifies that overhead is removed from the bandwidth estimate by
3412// testing that the maximum possible target payload rate is smaller than the
3413// maximum bandwidth estimate by the overhead rate.
michaelt273f31b2017-02-08 08:21:52 -08003414TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003415 test::ScopedFieldTrials override_field_trials(
3416 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3417 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3418 public test::FakeEncoder {
3419 public:
eladalon413ee9a2017-08-22 04:02:52 -07003420 explicit RemoveOverheadFromBandwidthTest(
3421 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003422 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3423 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003424 task_queue_(task_queue),
michaelta3328772016-11-29 09:25:03 -08003425 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003426 max_bitrate_bps_(0),
3427 first_packet_sent_(false),
3428 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003429
3430 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
3431 uint32_t frameRate) override {
3432 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003433 // Wait for the first sent packet so that videosendstream knows
3434 // rtp_overhead.
3435 if (first_packet_sent_) {
3436 max_bitrate_bps_ = bitrate.get_sum_bps();
3437 bitrate_changed_event_.Set();
3438 }
michaelta3328772016-11-29 09:25:03 -08003439 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3440 }
3441
3442 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3443 call_ = sender_call;
3444 }
3445
3446 void ModifyVideoConfigs(
3447 VideoSendStream::Config* send_config,
3448 std::vector<VideoReceiveStream::Config>* receive_configs,
3449 VideoEncoderConfig* encoder_config) override {
3450 send_config->rtp.max_packet_size = 1200;
3451 send_config->encoder_settings.encoder = this;
3452 EXPECT_FALSE(send_config->rtp.extensions.empty());
3453 }
3454
michaelt192132e2017-01-26 09:05:27 -08003455 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3456 rtc::CritScope lock(&crit_);
3457 first_packet_sent_ = true;
3458 return SEND_PACKET;
3459 }
3460
michaelta3328772016-11-29 09:25:03 -08003461 void PerformTest() override {
michaelta3328772016-11-29 09:25:03 -08003462 Call::Config::BitrateConfig bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003463 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003464 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003465 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003466 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3467 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003468 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003469 task_queue_->SendTask([this, &bitrate_config]() {
3470 call_->SetBitrateConfig(bitrate_config);
3471 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
3472 });
michaelta3328772016-11-29 09:25:03 -08003473
3474 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003475 // overhead of 40B per packet video produces 2240bps overhead.
3476 // So the encoder BW should be set to 57760bps.
3477 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
michaelta3328772016-11-29 09:25:03 -08003478 {
3479 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003480 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003481 }
3482 }
3483
3484 private:
eladalon413ee9a2017-08-22 04:02:52 -07003485 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelta3328772016-11-29 09:25:03 -08003486 Call* call_;
3487 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003488 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3489 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003490 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003491 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003492 RunBaseTest(&test);
3493}
3494
sprang168794c2017-07-06 04:38:06 -07003495TEST_F(VideoSendStreamTest, SendsKeepAlive) {
3496 const int kTimeoutMs = 50; // Really short timeout for testing.
sprang168794c2017-07-06 04:38:06 -07003497
3498 class KeepaliveObserver : public test::SendTest {
3499 public:
3500 KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
3501
sprangdb2a9fc2017-08-09 06:42:32 -07003502 void OnRtpTransportControllerSendCreated(
3503 RtpTransportControllerSend* controller) override {
3504 RtpKeepAliveConfig config;
3505 config.timeout_interval_ms = kTimeoutMs;
3506 config.payload_type = CallTest::kDefaultKeepalivePayloadType;
3507 controller->SetKeepAliveConfig(config);
sprange5c4a812017-07-11 03:44:17 -07003508 }
3509
sprang168794c2017-07-06 04:38:06 -07003510 private:
3511 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3512 RTPHeader header;
3513 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3514
sprangd2702ef2017-07-10 08:41:10 -07003515 if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
sprang168794c2017-07-06 04:38:06 -07003516 // The video stream has started. Stop it now.
3517 if (capturer_)
3518 capturer_->Stop();
3519 } else {
3520 observation_complete_.Set();
3521 }
3522
3523 return SEND_PACKET;
3524 }
3525
sprang168794c2017-07-06 04:38:06 -07003526 void PerformTest() override {
3527 EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
3528 }
3529
3530 void OnFrameGeneratorCapturerCreated(
3531 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3532 capturer_ = frame_generator_capturer;
3533 }
3534
3535 test::FrameGeneratorCapturer* capturer_ = nullptr;
3536 } test;
3537
3538 RunBaseTest(&test);
3539}
3540
Erik Språng7c8cca32017-10-24 17:05:18 +02003541TEST_F(VideoSendStreamTest, ConfiguresAlrWhenSendSideOn) {
3542 const std::string kAlrProbingExperiment =
3543 std::string(AlrDetector::kScreenshareProbingBweExperimentName) +
3544 "/1.1,2875,85,20,-20,0/";
3545 test::ScopedFieldTrials alr_experiment(kAlrProbingExperiment);
3546 class PacingFactorObserver : public test::SendTest {
3547 public:
3548 PacingFactorObserver(bool configure_send_side, float expected_pacing_factor)
3549 : test::SendTest(kDefaultTimeoutMs),
3550 configure_send_side_(configure_send_side),
3551 expected_pacing_factor_(expected_pacing_factor),
3552 paced_sender_(nullptr) {}
3553
3554 void ModifyVideoConfigs(
3555 VideoSendStream::Config* send_config,
3556 std::vector<VideoReceiveStream::Config>* receive_configs,
3557 VideoEncoderConfig* encoder_config) override {
3558 // Check if send-side bwe extension is already present, and remove it if
3559 // it is not desired.
3560 bool has_send_side = false;
3561 for (auto it = send_config->rtp.extensions.begin();
3562 it != send_config->rtp.extensions.end(); ++it) {
3563 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3564 if (configure_send_side_) {
3565 has_send_side = true;
3566 } else {
3567 send_config->rtp.extensions.erase(it);
3568 }
3569 break;
3570 }
3571 }
3572
3573 if (configure_send_side_ && !has_send_side) {
3574 // Want send side, not present by default, so add it.
3575 send_config->rtp.extensions.emplace_back(
3576 RtpExtension::kTransportSequenceNumberUri,
3577 RtpExtension::kTransportSequenceNumberDefaultId);
3578 }
3579
3580 // ALR only enabled for screenshare.
3581 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3582 }
3583
3584 void OnRtpTransportControllerSendCreated(
3585 RtpTransportControllerSend* controller) override {
3586 // Grab a reference to the pacer.
3587 paced_sender_ = controller->pacer();
3588 }
3589
3590 void OnVideoStreamsCreated(
3591 VideoSendStream* send_stream,
3592 const std::vector<VideoReceiveStream*>& receive_streams) override {
3593 // Video streams created, check that pacer is correctly configured.
3594 EXPECT_EQ(expected_pacing_factor_, paced_sender_->GetPacingFactor());
3595 observation_complete_.Set();
3596 }
3597
3598 void PerformTest() override {
3599 EXPECT_TRUE(Wait()) << "Timed out while waiting for pacer config.";
3600 }
3601
3602 private:
3603 const bool configure_send_side_;
3604 const float expected_pacing_factor_;
3605 const PacedSender* paced_sender_;
3606 };
3607
3608 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
3609 PacingFactorObserver test_with_send_side(true, 1.1f);
3610 RunBaseTest(&test_with_send_side);
3611
3612 // Send-side bwe off, use default pacing factor.
3613 PacingFactorObserver test_without_send_side(
3614 false, PacedSender::kDefaultPaceMultiplier);
3615 RunBaseTest(&test_without_send_side);
3616}
3617
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003618} // namespace webrtc