blob: 52699db3c2cf5151683be6e6aa138f175b88a390 [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 {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100155 RTC_LOG(LS_WARNING)
156 << "Got a packet with zero absoluteSendTime, waiting"
157 " for another packet...";
skvladc3f35152016-09-02 13:23:46 -0700158 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000159
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000160 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000161 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000162
stefanff483612015-12-21 03:14:00 -0800163 void ModifyVideoConfigs(
164 VideoSendStream::Config* send_config,
165 std::vector<VideoReceiveStream::Config>* receive_configs,
166 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200167 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100168 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700169 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000170 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000171
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000172 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100173 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000174 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000175 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000176
stefane74eef12016-01-08 06:47:13 -0800177 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000178}
179
pbos@webrtc.org29023282013-09-11 10:14:56 +0000180TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000181 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000182 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000183 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000184 TransmissionTimeOffsetObserver()
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000185 : SendTest(kDefaultTimeoutMs),
186 encoder_(Clock::GetRealTimeClock(), kEncodeDelayMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000187 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100188 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000189 }
190
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000191 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000192 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000193 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000194 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000195
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000196 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
197 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000198 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000199 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100200 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000201
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000202 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000203 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000204
stefanff483612015-12-21 03:14:00 -0800205 void ModifyVideoConfigs(
206 VideoSendStream::Config* send_config,
207 std::vector<VideoReceiveStream::Config>* receive_configs,
208 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000209 send_config->encoder_settings.encoder = &encoder_;
Stefan Holmer12952972015-10-29 15:13:24 +0100210 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700211 send_config->rtp.extensions.push_back(RtpExtension(
212 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000213 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000214
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000215 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100216 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000217 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000218
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000219 test::DelayedEncoder encoder_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000220 } test;
221
stefane74eef12016-01-08 06:47:13 -0800222 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000223}
224
sprang867fb522015-08-03 04:38:41 -0700225TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700226 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700227 class TransportWideSequenceNumberObserver : public test::SendTest {
228 public:
229 TransportWideSequenceNumberObserver()
230 : SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) {
231 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
232 kRtpExtensionTransportSequenceNumber, kExtensionId));
233 }
234
235 private:
236 Action OnSendRtp(const uint8_t* packet, size_t length) override {
237 RTPHeader header;
238 EXPECT_TRUE(parser_->Parse(packet, length, &header));
239
240 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
241 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
242 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
243
Peter Boström5811a392015-12-10 13:02:50 +0100244 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700245
246 return SEND_PACKET;
247 }
248
stefanff483612015-12-21 03:14:00 -0800249 void ModifyVideoConfigs(
250 VideoSendStream::Config* send_config,
251 std::vector<VideoReceiveStream::Config>* receive_configs,
252 VideoEncoderConfig* encoder_config) override {
sprang867fb522015-08-03 04:38:41 -0700253 send_config->encoder_settings.encoder = &encoder_;
sprang867fb522015-08-03 04:38:41 -0700254 }
255
256 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100257 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700258 }
259
260 test::FakeEncoder encoder_;
261 } test;
262
stefane74eef12016-01-08 06:47:13 -0800263 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700264}
265
perkj803d97f2016-11-01 11:45:46 -0700266TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
267 class VideoRotationObserver : public test::SendTest {
268 public:
269 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
270 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
271 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
272 }
273
274 Action OnSendRtp(const uint8_t* packet, size_t length) override {
275 RTPHeader header;
276 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700277 // Only the last packet of the frame is required to have the extension.
278 if (!header.markerBit)
279 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700280 EXPECT_TRUE(header.extension.hasVideoRotation);
281 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
282 observation_complete_.Set();
283 return SEND_PACKET;
284 }
285
286 void ModifyVideoConfigs(
287 VideoSendStream::Config* send_config,
288 std::vector<VideoReceiveStream::Config>* receive_configs,
289 VideoEncoderConfig* encoder_config) override {
290 send_config->rtp.extensions.clear();
291 send_config->rtp.extensions.push_back(RtpExtension(
292 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
293 }
294
295 void OnFrameGeneratorCapturerCreated(
296 test::FrameGeneratorCapturer* frame_generator_capturer) override {
297 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
298 }
299
300 void PerformTest() override {
301 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
302 }
303 } test;
304
305 RunBaseTest(&test);
306}
307
ilnik00d802b2017-04-11 10:34:31 -0700308TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700309 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700310 public:
ilnik10894992017-06-21 08:23:19 -0700311 VideoContentTypeObserver() : SendTest(kDefaultTimeoutMs) {
ilnik00d802b2017-04-11 10:34:31 -0700312 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
313 kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
314 }
315
316 Action OnSendRtp(const uint8_t* packet, size_t length) override {
317 RTPHeader header;
318 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700319 // Only the last packet of the frame must have extension.
320 if (!header.markerBit)
321 return SEND_PACKET;
ilnik00d802b2017-04-11 10:34:31 -0700322 EXPECT_TRUE(header.extension.hasVideoContentType);
ilnik6d5b4d62017-08-30 03:32:14 -0700323 EXPECT_TRUE(videocontenttypehelpers::IsScreenshare(
324 header.extension.videoContentType));
ilnik00d802b2017-04-11 10:34:31 -0700325 observation_complete_.Set();
326 return SEND_PACKET;
327 }
328
329 void ModifyVideoConfigs(
330 VideoSendStream::Config* send_config,
331 std::vector<VideoReceiveStream::Config>* receive_configs,
332 VideoEncoderConfig* encoder_config) override {
333 send_config->rtp.extensions.clear();
334 send_config->rtp.extensions.push_back(
335 RtpExtension(RtpExtension::kVideoContentTypeUri,
336 test::kVideoContentTypeExtensionId));
337 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
338 }
339
340 void PerformTest() override {
341 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
342 }
343 } test;
344
345 RunBaseTest(&test);
346}
347
ilnik04f4d122017-06-19 07:18:55 -0700348TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700349 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700350 public:
ilnik10894992017-06-21 08:23:19 -0700351 VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
ilnik04f4d122017-06-19 07:18:55 -0700352 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
353 kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
354 }
355
356 Action OnSendRtp(const uint8_t* packet, size_t length) override {
357 RTPHeader header;
358 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700359 // Only the last packet of the frame must have extension.
360 if (!header.markerBit)
361 return SEND_PACKET;
362 EXPECT_TRUE(header.extension.has_video_timing);
363 observation_complete_.Set();
ilnik04f4d122017-06-19 07:18:55 -0700364 return SEND_PACKET;
365 }
366
367 void ModifyVideoConfigs(
368 VideoSendStream::Config* send_config,
369 std::vector<VideoReceiveStream::Config>* receive_configs,
370 VideoEncoderConfig* encoder_config) override {
371 send_config->rtp.extensions.clear();
372 send_config->rtp.extensions.push_back(RtpExtension(
373 RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
374 }
375
376 void PerformTest() override {
377 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
378 }
379 } test;
380
381 RunBaseTest(&test);
382}
383
danilchap901b2df2017-07-28 08:56:04 -0700384class FakeReceiveStatistics : public ReceiveStatisticsProvider {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000385 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000386 FakeReceiveStatistics(uint32_t send_ssrc,
387 uint32_t last_sequence_number,
388 uint32_t cumulative_lost,
danilchap901b2df2017-07-28 08:56:04 -0700389 uint8_t fraction_lost) {
390 stat_.SetMediaSsrc(send_ssrc);
391 stat_.SetExtHighestSeqNum(last_sequence_number);
392 stat_.SetCumulativeLost(cumulative_lost);
393 stat_.SetFractionLost(fraction_lost);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000394 }
395
danilchap901b2df2017-07-28 08:56:04 -0700396 std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override {
397 EXPECT_GE(max_blocks, 1u);
398 return {stat_};
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000399 }
400
401 private:
danilchap901b2df2017-07-28 08:56:04 -0700402 rtcp::ReportBlock stat_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000403};
404
brandtre602f0a2016-10-31 03:40:49 -0700405class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100406 public:
brandtre602f0a2016-10-31 03:40:49 -0700407 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800408 bool use_nack,
409 bool expect_red,
410 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800411 const std::string& codec,
412 VideoEncoder* encoder)
brandtr20d45472017-01-02 00:34:27 -0800413 : EndToEndTest(kTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800414 encoder_(encoder),
Peter Boström39593972016-02-15 11:27:15 +0100415 payload_name_(codec),
416 use_nack_(use_nack),
417 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700418 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800419 sent_media_(false),
420 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800421 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100422
brandtr20d45472017-01-02 00:34:27 -0800423 // Some of the test cases are expected to time out and thus we are using
424 // a shorter timeout window than the default here.
425 static constexpr size_t kTimeoutMs = 10000;
426
Stefan Holmer4654d202015-12-08 09:10:43 +0100427 private:
428 Action OnSendRtp(const uint8_t* packet, size_t length) override {
429 RTPHeader header;
430 EXPECT_TRUE(parser_->Parse(packet, length, &header));
431
Stefan Holmer4654d202015-12-08 09:10:43 +0100432 int encapsulated_payload_type = -1;
433 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100434 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100435 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
436 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100437 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100438 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
439 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100440 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100441 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100442 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
443 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100444 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
445 length) {
446 // Not padding-only, media received outside of RED.
447 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800448 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100449 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100450 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000451
Stefan Holmer4654d202015-12-08 09:10:43 +0100452 if (header_extensions_enabled_) {
453 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
454 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
455 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
456 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
457 // 24 bits wrap.
458 EXPECT_GT(prev_header_.extension.absoluteSendTime,
459 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000460 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100461 EXPECT_GE(header.extension.absoluteSendTime,
462 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200463 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100464 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
465 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
466 prev_header_.extension.transportSequenceNumber;
467 EXPECT_EQ(1, seq_num_diff);
468 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200469
Stefan Holmer4654d202015-12-08 09:10:43 +0100470 if (encapsulated_payload_type != -1) {
471 if (encapsulated_payload_type ==
472 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700473 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800474 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100475 } else {
brandtr65a1e772016-12-12 01:54:58 -0800476 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000477 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000478 }
479
brandtr20d45472017-01-02 00:34:27 -0800480 if (sent_media_ && sent_ulpfec_) {
481 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100482 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000483
Stefan Holmer4654d202015-12-08 09:10:43 +0100484 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000485
Stefan Holmer4654d202015-12-08 09:10:43 +0100486 return SEND_PACKET;
487 }
488
eladalon413ee9a2017-08-22 04:02:52 -0700489 test::PacketTransport* CreateSendTransport(
490 test::SingleThreadedTaskQueueForTesting* task_queue,
491 Call* sender_call) override {
Peter Boström39593972016-02-15 11:27:15 +0100492 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
493 // Configure some network delay.
494 const int kNetworkDelayMs = 100;
495 FakeNetworkPipe::Config config;
brandtr65a1e772016-12-12 01:54:58 -0800496 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100497 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700498 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700499 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700500 VideoSendStreamTest::payload_type_map_, config);
Peter Boström39593972016-02-15 11:27:15 +0100501 }
502
stefanff483612015-12-21 03:14:00 -0800503 void ModifyVideoConfigs(
504 VideoSendStream::Config* send_config,
505 std::vector<VideoReceiveStream::Config>* receive_configs,
506 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100507 if (use_nack_) {
508 send_config->rtp.nack.rtp_history_ms =
509 (*receive_configs)[0].rtp.nack.rtp_history_ms =
510 VideoSendStreamTest::kNackRtpHistoryMs;
511 }
brandtr696c9c62016-12-19 05:47:28 -0800512 send_config->encoder_settings.encoder = encoder_;
Peter Boström39593972016-02-15 11:27:15 +0100513 send_config->encoder_settings.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700514 send_config->rtp.ulpfec.red_payload_type =
515 VideoSendStreamTest::kRedPayloadType;
516 send_config->rtp.ulpfec.ulpfec_payload_type =
517 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800518 EXPECT_FALSE(send_config->rtp.extensions.empty());
519 if (!header_extensions_enabled_) {
520 send_config->rtp.extensions.clear();
521 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100522 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700523 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100524 }
nisse3b3622f2017-09-26 02:49:21 -0700525 (*receive_configs)[0].rtp.red_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700526 send_config->rtp.ulpfec.red_payload_type;
nisse3b3622f2017-09-26 02:49:21 -0700527 (*receive_configs)[0].rtp.ulpfec_payload_type =
brandtrb5f2c3f2016-10-04 23:28:39 -0700528 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100529 }
530
531 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800532 EXPECT_EQ(expect_ulpfec_, Wait())
533 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100534 }
535
brandtr696c9c62016-12-19 05:47:28 -0800536 VideoEncoder* const encoder_;
537 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100538 const bool use_nack_;
539 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700540 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800541 bool sent_media_;
542 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100543 bool header_extensions_enabled_;
544 RTPHeader prev_header_;
545};
546
brandtre602f0a2016-10-31 03:40:49 -0700547TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800548 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
549 UlpfecObserver test(true, false, true, true, "VP8", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800550 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100551}
552
brandtre602f0a2016-10-31 03:40:49 -0700553TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800554 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
555 UlpfecObserver test(false, false, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100556 RunBaseTest(&test);
557}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000558
stefan60e10c72017-08-23 10:40:00 -0700559class VideoSendStreamWithoutUlpfecTest : public VideoSendStreamTest {
560 protected:
561 VideoSendStreamWithoutUlpfecTest()
562 : field_trial_("WebRTC-DisableUlpFecExperiment/Enabled/") {}
563
564 test::ScopedFieldTrials field_trial_;
565};
566
567TEST_F(VideoSendStreamWithoutUlpfecTest, NoUlpfecIfDisabledThroughFieldTrial) {
568 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
569 UlpfecObserver test(false, false, true, false, "VP8", encoder.get());
570 RunBaseTest(&test);
571}
572
Peter Boström39593972016-02-15 11:27:15 +0100573// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
574// since we'll still have to re-request FEC packets, effectively wasting
575// bandwidth since the receiver has to wait for FEC retransmissions to determine
576// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700577TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800578 std::unique_ptr<VideoEncoder> encoder(
579 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
580 UlpfecObserver test(false, true, true, false, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100581 RunBaseTest(&test);
582}
583
584// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800585TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800586 std::unique_ptr<VideoEncoder> encoder(
587 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
588 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100589 RunBaseTest(&test);
590}
591
danilchap9f5b6222017-03-02 06:22:21 -0800592// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
593TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800594 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
595 UlpfecObserver test(false, true, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100596 RunBaseTest(&test);
597}
598
Peter Boström12996152016-05-14 02:03:18 +0200599#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800600// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
601TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800602 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
603 UlpfecObserver test(false, true, true, true, "VP9", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800604 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000605}
Peter Boström12996152016-05-14 02:03:18 +0200606#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000607
brandtre78d2662017-01-16 05:57:16 -0800608TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800609 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800610 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800611 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
612 RunBaseTest(&test);
613}
614
brandtr39f97292016-11-16 22:57:50 -0800615// TODO(brandtr): Move these FlexFEC tests when we have created
616// FlexfecSendStream.
617class FlexfecObserver : public test::EndToEndTest {
618 public:
619 FlexfecObserver(bool header_extensions_enabled,
620 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800621 const std::string& codec,
622 VideoEncoder* encoder)
brandtr39f97292016-11-16 22:57:50 -0800623 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800624 encoder_(encoder),
brandtr39f97292016-11-16 22:57:50 -0800625 payload_name_(codec),
626 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800627 sent_media_(false),
628 sent_flexfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800629 header_extensions_enabled_(header_extensions_enabled) {}
brandtr39f97292016-11-16 22:57:50 -0800630
631 size_t GetNumFlexfecStreams() const override { return 1; }
632
633 private:
634 Action OnSendRtp(const uint8_t* packet, size_t length) override {
635 RTPHeader header;
636 EXPECT_TRUE(parser_->Parse(packet, length, &header));
637
brandtr39f97292016-11-16 22:57:50 -0800638 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
639 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
640 sent_flexfec_ = true;
641 } else {
642 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
643 header.payloadType);
644 EXPECT_EQ(VideoSendStreamTest::kVideoSendSsrcs[0], header.ssrc);
645 sent_media_ = true;
646 }
647
648 if (header_extensions_enabled_) {
649 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
650 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
651 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
652 }
653
brandtr0c5a1542016-11-23 04:42:26 -0800654 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800655 observation_complete_.Set();
656 }
657
658 return SEND_PACKET;
659 }
660
eladalon413ee9a2017-08-22 04:02:52 -0700661 test::PacketTransport* CreateSendTransport(
662 test::SingleThreadedTaskQueueForTesting* task_queue,
663 Call* sender_call) override {
brandtr39f97292016-11-16 22:57:50 -0800664 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
665 // Therefore we need some network delay.
666 const int kNetworkDelayMs = 100;
667 FakeNetworkPipe::Config config;
brandtrd654a9b2016-12-05 05:38:19 -0800668 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800669 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700670 return new test::PacketTransport(
eladalon413ee9a2017-08-22 04:02:52 -0700671 task_queue, sender_call, this, test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -0700672 VideoSendStreamTest::payload_type_map_, config);
brandtr39f97292016-11-16 22:57:50 -0800673 }
674
675 void ModifyVideoConfigs(
676 VideoSendStream::Config* send_config,
677 std::vector<VideoReceiveStream::Config>* receive_configs,
678 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800679 if (use_nack_) {
680 send_config->rtp.nack.rtp_history_ms =
681 (*receive_configs)[0].rtp.nack.rtp_history_ms =
682 VideoSendStreamTest::kNackRtpHistoryMs;
683 }
brandtr696c9c62016-12-19 05:47:28 -0800684 send_config->encoder_settings.encoder = encoder_;
brandtr39f97292016-11-16 22:57:50 -0800685 send_config->encoder_settings.payload_name = payload_name_;
686 if (header_extensions_enabled_) {
687 send_config->rtp.extensions.push_back(RtpExtension(
688 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
689 send_config->rtp.extensions.push_back(RtpExtension(
690 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800691 } else {
692 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800693 }
694 }
695
696 void PerformTest() override {
697 EXPECT_TRUE(Wait())
698 << "Timed out waiting for FlexFEC and/or media packets.";
699 }
700
brandtr696c9c62016-12-19 05:47:28 -0800701 VideoEncoder* const encoder_;
702 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800703 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800704 bool sent_media_;
705 bool sent_flexfec_;
706 bool header_extensions_enabled_;
707};
708
brandtrd654a9b2016-12-05 05:38:19 -0800709TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800710 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
711 FlexfecObserver test(false, false, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800712 RunBaseTest(&test);
713}
714
715TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800716 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
717 FlexfecObserver test(false, true, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800718 RunBaseTest(&test);
719}
720
brandtr39f97292016-11-16 22:57:50 -0800721TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800722 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
723 FlexfecObserver test(true, false, "VP8", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800724 RunBaseTest(&test);
725}
726
brandtr39f97292016-11-16 22:57:50 -0800727#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800728TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800729 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
730 FlexfecObserver test(false, false, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800731 RunBaseTest(&test);
732}
733
brandtrd654a9b2016-12-05 05:38:19 -0800734TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800735 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
736 FlexfecObserver test(false, true, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800737 RunBaseTest(&test);
738}
739#endif // defined(RTC_DISABLE_VP9)
740
brandtrd654a9b2016-12-05 05:38:19 -0800741TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
brandtr696c9c62016-12-19 05:47:28 -0800742 std::unique_ptr<VideoEncoder> encoder(
743 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
744 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800745 RunBaseTest(&test);
746}
747
brandtrd654a9b2016-12-05 05:38:19 -0800748TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
brandtr696c9c62016-12-19 05:47:28 -0800749 std::unique_ptr<VideoEncoder> encoder(
750 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
751 FlexfecObserver test(false, true, "H264", encoder.get());
752 RunBaseTest(&test);
753}
754
brandtre78d2662017-01-16 05:57:16 -0800755TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800756 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800757 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800758 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800759 RunBaseTest(&test);
760}
761
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000762void VideoSendStreamTest::TestNackRetransmission(
763 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000764 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000765 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000766 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000767 explicit NackObserver(uint32_t retransmit_ssrc,
768 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000769 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000770 send_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000771 retransmit_ssrc_(retransmit_ssrc),
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000772 retransmit_payload_type_(retransmit_payload_type),
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000773 nacked_sequence_number_(-1) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000774 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000775
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000776 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000777 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000778 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000779 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000780
781 // Nack second packet after receiving the third one.
782 if (++send_count_ == 3) {
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000783 uint16_t nack_sequence_number = header.sequenceNumber - 1;
784 nacked_sequence_number_ = nack_sequence_number;
danilchap8a1d2a32017-08-01 03:21:37 -0700785 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), nullptr,
terelius429c3452016-01-21 05:42:04 -0800786 nullptr, nullptr, transport_adapter_.get());
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000787
pbosda903ea2015-10-02 02:36:56 -0700788 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100789 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000790
791 RTCPSender::FeedbackState feedback_state;
792
793 EXPECT_EQ(0,
794 rtcp_sender.SendRTCP(
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000795 feedback_state, kRtcpNack, 1, &nack_sequence_number));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000796 }
797
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000798 uint16_t sequence_number = header.sequenceNumber;
799
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000800 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100801 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
802 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000803 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000804 const uint8_t* rtx_header = packet + header.headerLength;
805 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
806 }
807
808 if (sequence_number == nacked_sequence_number_) {
809 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000810 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
Peter Boström5811a392015-12-10 13:02:50 +0100811 observation_complete_.Set();
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000812 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000813
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000814 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000815 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000816
stefanff483612015-12-21 03:14:00 -0800817 void ModifyVideoConfigs(
818 VideoSendStream::Config* send_config,
819 std::vector<VideoReceiveStream::Config>* receive_configs,
820 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700821 transport_adapter_.reset(
822 new internal::TransportAdapter(send_config->send_transport));
823 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000824 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000825 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100826 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000827 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
828 }
829
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000830 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100831 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000832 }
833
kwiberg27f982b2016-03-01 11:52:33 -0800834 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000835 int send_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000836 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000837 uint8_t retransmit_payload_type_;
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000838 int nacked_sequence_number_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000839 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000840
stefane74eef12016-01-08 06:47:13 -0800841 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000842}
843
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000844TEST_F(VideoSendStreamTest, RetransmitsNack) {
845 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100846 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000847}
848
849TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
850 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000851 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000852}
853
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000854void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
855 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000856 // Use a fake encoder to output a frame of every size in the range [90, 290],
857 // for each size making sure that the exact number of payload bytes received
858 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000859 static const size_t kMaxPacketSize = 128;
860 static const size_t start = 90;
861 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000862
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000863 // Observer that verifies that the expected number of packets and bytes
864 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000865 class FrameFragmentationTest : public test::SendTest,
866 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000867 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000868 FrameFragmentationTest(size_t max_packet_size,
869 size_t start_size,
870 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000871 bool test_generic_packetization,
872 bool use_fec)
873 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000874 encoder_(stop),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000875 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000876 stop_size_(stop_size),
877 test_generic_packetization_(test_generic_packetization),
878 use_fec_(use_fec),
879 packet_count_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000880 accumulated_size_(0),
881 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000882 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000883 current_size_rtp_(start_size),
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700884 current_size_frame_(static_cast<int>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000885 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000886 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700887 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000888 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000889
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000890 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000891 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000892 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000893 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000894 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000895
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000896 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000897
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000898 if (use_fec_) {
899 uint8_t payload_type = packet[header.headerLength];
900 bool is_fec = header.payloadType == kRedPayloadType &&
901 payload_type == kUlpfecPayloadType;
902 if (is_fec) {
903 fec_packet_received_ = true;
904 return SEND_PACKET;
905 }
906 }
907
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000908 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000909
910 if (use_fec_)
911 TriggerLossReport(header);
912
913 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200914 size_t overhead = header.headerLength + header.paddingLength;
915 // Only remove payload header and RED header if the packet actually
916 // contains payload.
917 if (length > overhead) {
918 overhead += (1 /* Generic header */);
919 if (use_fec_)
920 overhead += 1; // RED for FEC header.
921 }
922 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000923 accumulated_payload_ += length - overhead;
924 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000925
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000926 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000927 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000928 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
929 // With FEC enabled, frame size is incremented asynchronously, so
930 // "old" frames one byte too small may arrive. Accept, but don't
931 // increase expected frame size.
932 accumulated_size_ = 0;
933 accumulated_payload_ = 0;
934 return SEND_PACKET;
935 }
936
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000937 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000938 if (test_generic_packetization_) {
939 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
940 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000941
942 // Last packet of frame; reset counters.
943 accumulated_size_ = 0;
944 accumulated_payload_ = 0;
945 if (current_size_rtp_ == stop_size_) {
946 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +0100947 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000948 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000949 // Increase next expected frame size. If testing with FEC, make sure
950 // a FEC packet has been received for this frame size before
951 // proceeding, to make sure that redundancy packets don't exceed
952 // size limit.
953 if (!use_fec_) {
954 ++current_size_rtp_;
955 } else if (fec_packet_received_) {
956 fec_packet_received_ = false;
957 ++current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700958
959 rtc::CritScope lock(&mutex_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000960 ++current_size_frame_;
961 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000962 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000963 }
964
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000965 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000966 }
967
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000968 void TriggerLossReport(const RTPHeader& header) {
969 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -0700970 const int kLossPercent = 5;
971 if (packet_count_++ % (100 / kLossPercent) != 0) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000972 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -0700973 kVideoSendSsrcs[0], header.sequenceNumber,
974 (packet_count_ * (100 - kLossPercent)) / 100, // Cumulative lost.
975 static_cast<uint8_t>((255 * kLossPercent) / 100)); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +0200976 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -0800977 &lossy_receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -0700978 transport_adapter_.get());
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000979
pbosda903ea2015-10-02 02:36:56 -0700980 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100981 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000982
983 RTCPSender::FeedbackState feedback_state;
984
985 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
986 }
987 }
988
nisseef8b61e2016-04-29 06:09:15 -0700989 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700990 rtc::CritScope lock(&mutex_);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000991 // Increase frame size for next encoded frame, in the context of the
992 // encoder thread.
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700993 if (!use_fec_ && current_size_frame_ < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000994 ++current_size_frame_;
995 }
Yuwei Huangd9f99c12017-10-24 15:40:52 -0700996 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_));
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000997 }
998
Stefan Holmere5904162015-03-26 11:11:06 +0100999 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07001000 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01001001 const int kMinBitrateBps = 30000;
1002 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
1003 return config;
1004 }
1005
stefanff483612015-12-21 03:14:00 -08001006 void ModifyVideoConfigs(
1007 VideoSendStream::Config* send_config,
1008 std::vector<VideoReceiveStream::Config>* receive_configs,
1009 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001010 transport_adapter_.reset(
1011 new internal::TransportAdapter(send_config->send_transport));
1012 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001013 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001014 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1015 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001016 }
1017
1018 if (!test_generic_packetization_)
1019 send_config->encoder_settings.payload_name = "VP8";
1020
1021 send_config->encoder_settings.encoder = &encoder_;
1022 send_config->rtp.max_packet_size = kMaxPacketSize;
1023 send_config->post_encode_callback = this;
1024
Erik Språng95261872015-04-10 11:58:49 +02001025 // Make sure there is at least one extension header, to make the RTP
1026 // header larger than the base length of 12 bytes.
1027 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001028
1029 // Setup screen content disables frame dropping which makes this easier.
1030 class VideoStreamFactory
1031 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1032 public:
1033 explicit VideoStreamFactory(size_t num_temporal_layers)
1034 : num_temporal_layers_(num_temporal_layers) {
1035 EXPECT_GT(num_temporal_layers, 0u);
1036 }
1037
1038 private:
1039 std::vector<VideoStream> CreateEncoderStreams(
1040 int width,
1041 int height,
1042 const VideoEncoderConfig& encoder_config) override {
1043 std::vector<VideoStream> streams =
1044 test::CreateVideoStreams(width, height, encoder_config);
1045 for (VideoStream& stream : streams) {
1046 stream.temporal_layer_thresholds_bps.resize(num_temporal_layers_ -
1047 1);
1048 }
1049 return streams;
1050 }
1051 const size_t num_temporal_layers_;
1052 };
1053
1054 encoder_config->video_stream_factory =
1055 new rtc::RefCountedObject<VideoStreamFactory>(2);
1056 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001057 }
1058
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001059 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001060 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001061 }
1062
kwiberg27f982b2016-03-01 11:52:33 -08001063 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001064 test::ConfigurableFrameSizeEncoder encoder_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001065
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001066 const size_t max_packet_size_;
1067 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001068 const bool test_generic_packetization_;
1069 const bool use_fec_;
1070
1071 uint32_t packet_count_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001072 size_t accumulated_size_;
1073 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001074 bool fec_packet_received_;
1075
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001076 size_t current_size_rtp_;
Yuwei Huangd9f99c12017-10-24 15:40:52 -07001077 rtc::CriticalSection mutex_;
1078 int current_size_frame_ RTC_GUARDED_BY(mutex_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001079 };
1080
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001081 // Don't auto increment if FEC is used; continue sending frame size until
1082 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001083 FrameFragmentationTest test(
1084 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001085
stefane74eef12016-01-08 06:47:13 -08001086 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001087}
1088
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001089// TODO(sprang): Is there any way of speeding up these tests?
1090TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
1091 TestPacketFragmentationSize(kGeneric, false);
1092}
1093
1094TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
1095 TestPacketFragmentationSize(kGeneric, true);
1096}
1097
1098TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
1099 TestPacketFragmentationSize(kVP8, false);
1100}
1101
1102TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
1103 TestPacketFragmentationSize(kVP8, true);
1104}
1105
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001106// The test will go through a number of phases.
1107// 1. Start sending packets.
1108// 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 +00001109// suspend the stream.
1110// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001111// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001112// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001113// When the stream is detected again, and the stats show that the stream
1114// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001115TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1116 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001117
nissed30a1112016-04-18 05:15:22 -07001118 class RembObserver : public test::SendTest,
1119 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001120 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001121 RembObserver()
1122 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001123 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001124 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001125 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001126 rtp_count_(0),
1127 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001128 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001129 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001130 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001131
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001132 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001133 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001134 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001135 ++rtp_count_;
1136 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001137 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001138 last_sequence_number_ = header.sequenceNumber;
1139
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001140 if (test_state_ == kBeforeSuspend) {
1141 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001142 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001143 test_state_ = kDuringSuspend;
1144 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001145 if (header.paddingLength == 0) {
1146 // Received non-padding packet during suspension period. Reset the
1147 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001148 suspended_frame_count_ = 0;
1149 }
stefanf116bd02015-10-27 08:29:42 -07001150 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001151 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001152 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001153 // Non-padding packet observed. Test is almost complete. Will just
1154 // have to wait for the stats to change.
1155 test_state_ = kWaitingForStats;
1156 }
stefanf116bd02015-10-27 08:29:42 -07001157 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001158 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001159 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001160 if (stats.suspended == false) {
1161 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001162 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001163 }
stefanf116bd02015-10-27 08:29:42 -07001164 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001165 }
1166
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001167 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001168 }
1169
perkj26091b12016-09-01 01:17:40 -07001170 // This method implements the rtc::VideoSinkInterface. This is called when
1171 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001172 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001173 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001174 if (test_state_ == kDuringSuspend &&
1175 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001176 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001177 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001178 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001179 test_state_ = kWaitingForPacket;
1180 }
1181 }
1182
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001183 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001184 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001185 low_remb_bps_ = value;
1186 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001187
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001188 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001189 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001190 high_remb_bps_ = value;
1191 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001192
stefanff483612015-12-21 03:14:00 -08001193 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001194 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001195 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001196 stream_ = send_stream;
1197 }
1198
stefanff483612015-12-21 03:14:00 -08001199 void ModifyVideoConfigs(
1200 VideoSendStream::Config* send_config,
1201 std::vector<VideoReceiveStream::Config>* receive_configs,
1202 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001203 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001204 transport_adapter_.reset(
1205 new internal::TransportAdapter(send_config->send_transport));
1206 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001207 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001208 send_config->pre_encode_callback = this;
1209 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001210 int min_bitrate_bps =
1211 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001212 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001213 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001214 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001215 min_bitrate_bps + threshold_window + 5000);
1216 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1217 }
1218
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001219 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001220 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001221 }
1222
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001223 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001224 kBeforeSuspend,
1225 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001226 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001227 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001228 };
1229
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001230 virtual void SendRtcpFeedback(int remb_value)
danilchapa37de392017-09-09 04:17:22 -07001231 RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001232 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1233 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001234 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -07001235 transport_adapter_.get());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001236
pbosda903ea2015-10-02 02:36:56 -07001237 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001238 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001239 if (remb_value > 0) {
Danil Chapovalovf74d6412017-10-18 13:32:57 +02001240 rtcp_sender.SetRemb(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001241 }
1242 RTCPSender::FeedbackState feedback_state;
1243 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1244 }
1245
kwiberg27f982b2016-03-01 11:52:33 -08001246 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001247 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001248 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001249
Peter Boströmf2f82832015-05-01 13:00:41 +02001250 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001251 TestState test_state_ RTC_GUARDED_BY(crit_);
1252 int rtp_count_ RTC_GUARDED_BY(crit_);
1253 int last_sequence_number_ RTC_GUARDED_BY(crit_);
1254 int suspended_frame_count_ RTC_GUARDED_BY(crit_);
1255 int low_remb_bps_ RTC_GUARDED_BY(crit_);
1256 int high_remb_bps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001257 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001258
stefane74eef12016-01-08 06:47:13 -08001259 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001260}
1261
perkj71ee44c2016-06-15 00:47:53 -07001262// This test that padding stops being send after a while if the Camera stops
1263// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001264TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001265 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001266 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001267 NoPaddingWhenVideoIsMuted()
1268 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001269 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001270 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001271 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +00001272 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001273
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001274 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001275 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001276 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001277 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001278
1279 RTPHeader header;
1280 parser_->Parse(packet, length, &header);
1281 const bool only_padding =
1282 header.headerLength + header.paddingLength == length;
1283
1284 if (test_state_ == kBeforeStopCapture) {
1285 capturer_->Stop();
1286 test_state_ = kWaitingForPadding;
1287 } else if (test_state_ == kWaitingForPadding && only_padding) {
1288 test_state_ = kWaitingForNoPackets;
1289 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1290 only_padding) {
1291 observation_complete_.Set();
1292 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001293 return SEND_PACKET;
1294 }
1295
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001296 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001297 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001298 const int kNoPacketsThresholdMs = 2000;
1299 if (test_state_ == kWaitingForNoPackets &&
1300 (last_packet_time_ms_ > 0 &&
1301 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1302 kNoPacketsThresholdMs)) {
1303 capturer_->Start();
1304 test_state_ = kWaitingForPaddingAfterCameraRestart;
1305 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001306 return SEND_PACKET;
1307 }
1308
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001309 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001310
nisseef8b61e2016-04-29 06:09:15 -07001311 void OnFrameGeneratorCapturerCreated(
1312 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001313 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001314 capturer_ = frame_generator_capturer;
1315 }
1316
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001317 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001318 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001319 << "Timed out while waiting for RTP packets to stop being sent.";
1320 }
1321
perkj71ee44c2016-06-15 00:47:53 -07001322 enum TestState {
1323 kBeforeStopCapture,
1324 kWaitingForPadding,
1325 kWaitingForNoPackets,
1326 kWaitingForPaddingAfterCameraRestart
1327 };
1328
1329 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001330 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001331 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001332 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07001333 int64_t last_packet_time_ms_ RTC_GUARDED_BY(crit_);
1334 test::FrameGeneratorCapturer* capturer_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001335 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001336
stefane74eef12016-01-08 06:47:13 -08001337 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001338}
1339
isheriffcc5903e2016-10-04 08:29:38 -07001340TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1341 const int kCapacityKbps = 10000; // 10 Mbps
1342 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1343 public:
1344 PaddingIsPrimarilyRetransmissions()
1345 : EndToEndTest(kDefaultTimeoutMs),
1346 clock_(Clock::GetRealTimeClock()),
1347 padding_length_(0),
1348 total_length_(0),
1349 call_(nullptr) {}
1350
1351 private:
1352 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1353 call_ = sender_call;
1354 }
1355
1356 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1357 rtc::CritScope lock(&crit_);
1358
1359 RTPHeader header;
1360 parser_->Parse(packet, length, &header);
1361 padding_length_ += header.paddingLength;
1362 total_length_ += length;
1363 return SEND_PACKET;
1364 }
1365
eladalon413ee9a2017-08-22 04:02:52 -07001366 test::PacketTransport* CreateSendTransport(
1367 test::SingleThreadedTaskQueueForTesting* task_queue,
1368 Call* sender_call) override {
isheriffcc5903e2016-10-04 08:29:38 -07001369 const int kNetworkDelayMs = 50;
1370 FakeNetworkPipe::Config config;
1371 config.loss_percent = 10;
1372 config.link_capacity_kbps = kCapacityKbps;
1373 config.queue_delay_ms = kNetworkDelayMs;
eladalon413ee9a2017-08-22 04:02:52 -07001374 return new test::PacketTransport(task_queue, sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -07001375 test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -07001376 payload_type_map_, config);
isheriffcc5903e2016-10-04 08:29:38 -07001377 }
1378
1379 void ModifyVideoConfigs(
1380 VideoSendStream::Config* send_config,
1381 std::vector<VideoReceiveStream::Config>* receive_configs,
1382 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001383 // Turn on RTX.
1384 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1385 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001386 }
1387
1388 void PerformTest() override {
1389 // TODO(isheriff): Some platforms do not ramp up as expected to full
1390 // capacity due to packet scheduling delays. Fix that before getting
1391 // rid of this.
1392 SleepMs(5000);
1393 {
1394 rtc::CritScope lock(&crit_);
1395 // Expect padding to be a small percentage of total bytes sent.
1396 EXPECT_LT(padding_length_, .1 * total_length_);
1397 }
1398 }
1399
1400 rtc::CriticalSection crit_;
1401 Clock* const clock_;
danilchapa37de392017-09-09 04:17:22 -07001402 size_t padding_length_ RTC_GUARDED_BY(crit_);
1403 size_t total_length_ RTC_GUARDED_BY(crit_);
isheriffcc5903e2016-10-04 08:29:38 -07001404 Call* call_;
1405 } test;
1406
1407 RunBaseTest(&test);
1408}
1409
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001410// This test first observes "high" bitrate use at which point it sends a REMB to
1411// indicate that it should be lowered significantly. The test then observes that
1412// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1413// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001414//
1415// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1416// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001417TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1418 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001419 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001420 static const int kRembBitrateBps = 80000;
1421 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001422 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001423 public:
1424 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001425 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001426 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1427 stream_(nullptr),
1428 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001429
1430 private:
nisseef8b61e2016-04-29 06:09:15 -07001431 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001432 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001433 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001434
1435 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001436 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001437 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001438 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001439 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001440 if (!stats.substreams.empty()) {
1441 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001442 int total_bitrate_bps =
1443 stats.substreams.begin()->second.total_bitrate_bps;
1444 test::PrintResult("bitrate_stats_",
1445 "min_transmit_bitrate_low_remb",
1446 "bitrate_bps",
1447 static_cast<size_t>(total_bitrate_bps),
1448 "bps",
1449 false);
1450 if (total_bitrate_bps > kHighBitrateBps) {
Danil Chapovalov51e21aa2017-10-10 17:46:26 +02001451 rtp_rtcp_->SetRemb(kRembBitrateBps,
1452 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001453 rtp_rtcp_->Process();
1454 bitrate_capped_ = true;
1455 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001456 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001457 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001458 }
1459 }
stefanf116bd02015-10-27 08:29:42 -07001460 // Packets don't have to be delivered since the test is the receiver.
1461 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001462 }
1463
stefanff483612015-12-21 03:14:00 -08001464 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001465 VideoSendStream* send_stream,
1466 const std::vector<VideoReceiveStream*>& receive_streams) override {
1467 stream_ = send_stream;
1468 RtpRtcp::Configuration config;
1469 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001470 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001471 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
stefanf116bd02015-10-27 08:29:42 -07001472 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001473 }
1474
stefanff483612015-12-21 03:14:00 -08001475 void ModifyVideoConfigs(
1476 VideoSendStream::Config* send_config,
1477 std::vector<VideoReceiveStream::Config>* receive_configs,
1478 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001479 feedback_transport_.reset(
1480 new internal::TransportAdapter(send_config->send_transport));
1481 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001482 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001483 }
1484
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001485 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001486 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001487 << "Timeout while waiting for low bitrate stats after REMB.";
1488 }
1489
kwiberg27f982b2016-03-01 11:52:33 -08001490 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1491 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001492 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001493 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001494 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001495 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001496
stefane74eef12016-01-08 06:47:13 -08001497 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001498}
1499
Stefan Holmer280de9e2016-09-30 10:06:51 +02001500TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1501 static const int kStartBitrateBps = 300000;
1502 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001503 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001504 class ChangingNetworkRouteTest : public test::EndToEndTest {
1505 public:
eladalon413ee9a2017-08-22 04:02:52 -07001506 explicit ChangingNetworkRouteTest(
1507 test::SingleThreadedTaskQueueForTesting* task_queue)
1508 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1509 task_queue_(task_queue),
1510 call_(nullptr) {
Stefan Holmer280de9e2016-09-30 10:06:51 +02001511 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1512 kRtpExtensionTransportSequenceNumber, kExtensionId));
1513 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001514
1515 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1516 call_ = sender_call;
1517 }
1518
Stefan Holmer280de9e2016-09-30 10:06:51 +02001519 void ModifyVideoConfigs(
1520 VideoSendStream::Config* send_config,
1521 std::vector<VideoReceiveStream::Config>* receive_configs,
1522 VideoEncoderConfig* encoder_config) override {
1523 send_config->rtp.extensions.clear();
1524 send_config->rtp.extensions.push_back(RtpExtension(
1525 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1526 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1527 (*receive_configs)[0].rtp.transport_cc = true;
1528 }
1529
1530 void ModifyAudioConfigs(
1531 AudioSendStream::Config* send_config,
1532 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1533 send_config->rtp.extensions.clear();
1534 send_config->rtp.extensions.push_back(RtpExtension(
1535 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1536 (*receive_configs)[0].rtp.extensions.clear();
1537 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1538 (*receive_configs)[0].rtp.transport_cc = true;
1539 }
1540
Stefan Holmerbe402962016-07-08 16:16:41 +02001541 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1542 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1543 observation_complete_.Set();
1544 }
1545
1546 return SEND_PACKET;
1547 }
1548
1549 void PerformTest() override {
1550 rtc::NetworkRoute new_route(true, 10, 20, -1);
Stefan Holmerbe402962016-07-08 16:16:41 +02001551 Call::Config::BitrateConfig bitrate_config;
eladalon413ee9a2017-08-22 04:02:52 -07001552
1553 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1554 call_->OnNetworkRouteChanged("transport", new_route);
1555 bitrate_config.start_bitrate_bps = kStartBitrateBps;
1556 call_->SetBitrateConfig(bitrate_config);
1557 });
1558
Stefan Holmerbe402962016-07-08 16:16:41 +02001559 EXPECT_TRUE(Wait())
1560 << "Timed out while waiting for start bitrate to be exceeded.";
1561
eladalon413ee9a2017-08-22 04:02:52 -07001562 task_queue_->SendTask([this, &new_route, &bitrate_config]() {
1563 bitrate_config.start_bitrate_bps = -1;
1564 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
1565 call_->SetBitrateConfig(bitrate_config);
1566 // TODO(holmer): We should set the last sent packet id here and verify
1567 // that we correctly ignore any packet loss reported prior to that id.
1568 ++new_route.local_network_id;
1569 call_->OnNetworkRouteChanged("transport", new_route);
1570 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
1571 });
Stefan Holmerbe402962016-07-08 16:16:41 +02001572 }
1573
1574 private:
eladalon413ee9a2017-08-22 04:02:52 -07001575 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Stefan Holmerbe402962016-07-08 16:16:41 +02001576 Call* call_;
eladalon413ee9a2017-08-22 04:02:52 -07001577 } test(&task_queue_);
Stefan Holmerbe402962016-07-08 16:16:41 +02001578
1579 RunBaseTest(&test);
1580}
1581
michaelt79e05882016-11-08 02:50:09 -08001582TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
1583 class ChangingTransportOverheadTest : public test::EndToEndTest {
1584 public:
eladalon413ee9a2017-08-22 04:02:52 -07001585 explicit ChangingTransportOverheadTest(
1586 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelt79e05882016-11-08 02:50:09 -08001587 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07001588 task_queue_(task_queue),
michaelt79e05882016-11-08 02:50:09 -08001589 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001590 packets_sent_(0),
1591 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001592
1593 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1594 call_ = sender_call;
1595 }
1596
1597 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001598 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001599 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001600 if (++packets_sent_ < 100)
1601 return SEND_PACKET;
1602 observation_complete_.Set();
1603 return SEND_PACKET;
1604 }
1605
michaelta3328772016-11-29 09:25:03 -08001606 void ModifyVideoConfigs(
1607 VideoSendStream::Config* send_config,
1608 std::vector<VideoReceiveStream::Config>* receive_configs,
1609 VideoEncoderConfig* encoder_config) override {
1610 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1611 }
1612
michaelt79e05882016-11-08 02:50:09 -08001613 void PerformTest() override {
eladalon413ee9a2017-08-22 04:02:52 -07001614 task_queue_->SendTask([this]() {
1615 transport_overhead_ = 100;
1616 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1617 transport_overhead_);
1618 });
1619
michaelt79e05882016-11-08 02:50:09 -08001620 EXPECT_TRUE(Wait());
eladalon413ee9a2017-08-22 04:02:52 -07001621
sprang21253fc2017-02-27 03:35:47 -08001622 {
1623 rtc::CritScope cs(&lock_);
1624 packets_sent_ = 0;
1625 }
eladalon413ee9a2017-08-22 04:02:52 -07001626
1627 task_queue_->SendTask([this]() {
1628 transport_overhead_ = 500;
1629 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1630 transport_overhead_);
1631 });
1632
michaelt79e05882016-11-08 02:50:09 -08001633 EXPECT_TRUE(Wait());
1634 }
1635
1636 private:
eladalon413ee9a2017-08-22 04:02:52 -07001637 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelt79e05882016-11-08 02:50:09 -08001638 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001639 rtc::CriticalSection lock_;
danilchapa37de392017-09-09 04:17:22 -07001640 int packets_sent_ RTC_GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001641 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001642 const size_t kMaxRtpPacketSize = 1000;
eladalon413ee9a2017-08-22 04:02:52 -07001643 } test(&task_queue_);
michaelt79e05882016-11-08 02:50:09 -08001644
1645 RunBaseTest(&test);
1646}
1647
sprangf24a0642017-02-28 13:23:26 -08001648// Test class takes takes as argument a switch selecting if type switch should
1649// occur and a function pointer to reset the send stream. This is necessary
1650// since you cannot change the content type of a VideoSendStream, you need to
1651// recreate it. Stopping and recreating the stream can only be done on the main
1652// thread and in the context of VideoSendStreamTest (not BaseTest).
1653template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001654class MaxPaddingSetTest : public test::SendTest {
1655 public:
1656 static const uint32_t kMinTransmitBitrateBps = 400000;
1657 static const uint32_t kActualEncodeBitrateBps = 40000;
1658 static const uint32_t kMinPacketsToSend = 50;
1659
sprangf24a0642017-02-28 13:23:26 -08001660 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001661 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001662 content_switch_event_(false, false),
sprang9c0b5512016-07-06 00:54:28 -07001663 call_(nullptr),
1664 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001665 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001666 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001667 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001668 stream_resetter_(stream_reset_fun) {
1669 RTC_DCHECK(stream_resetter_);
1670 }
sprang9c0b5512016-07-06 00:54:28 -07001671
1672 void OnVideoStreamsCreated(
1673 VideoSendStream* send_stream,
1674 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001675 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001676 send_stream_ = send_stream;
1677 }
1678
1679 void ModifyVideoConfigs(
1680 VideoSendStream::Config* send_config,
1681 std::vector<VideoReceiveStream::Config>* receive_configs,
1682 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001683 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001684 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001685 encoder_config->min_transmit_bitrate_bps = 0;
1686 encoder_config->content_type =
1687 VideoEncoderConfig::ContentType::kRealtimeVideo;
1688 } else {
1689 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1690 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1691 }
sprangf24a0642017-02-28 13:23:26 -08001692 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001693 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001694 }
1695
1696 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1697 call_ = sender_call;
1698 }
1699
1700 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1701 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001702 if (running_without_padding_)
1703 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1704
1705 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1706 // we have reliable data.
1707 if (++packets_sent_ < kMinPacketsToSend)
1708 return SEND_PACKET;
1709
1710 if (running_without_padding_) {
1711 // We've sent kMinPacketsToSend packets with default configuration, switch
1712 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001713 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001714 packets_sent_ = 0;
1715 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1716 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001717 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001718 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001719 return SEND_PACKET;
1720 }
1721
1722 // Make sure the pacer has been configured with a min transmit bitrate.
1723 if (call_->GetStats().max_padding_bitrate_bps > 0)
1724 observation_complete_.Set();
1725
1726 return SEND_PACKET;
1727 }
1728
1729 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001730 if (RunningWithoutPadding()) {
1731 ASSERT_TRUE(
1732 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001733 (*stream_resetter_)(send_stream_config_, encoder_config_);
1734 }
1735
sprang9c0b5512016-07-06 00:54:28 -07001736 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1737 }
1738
1739 private:
sprangf24a0642017-02-28 13:23:26 -08001740 bool RunningWithoutPadding() const {
1741 rtc::CritScope lock(&crit_);
1742 return running_without_padding_;
1743 }
1744
sprang9c0b5512016-07-06 00:54:28 -07001745 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001746 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001747 Call* call_;
danilchapa37de392017-09-09 04:17:22 -07001748 VideoSendStream* send_stream_ RTC_GUARDED_BY(crit_);
sprangf24a0642017-02-28 13:23:26 -08001749 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001750 VideoEncoderConfig encoder_config_;
danilchapa37de392017-09-09 04:17:22 -07001751 uint32_t packets_sent_ RTC_GUARDED_BY(crit_);
sprang9c0b5512016-07-06 00:54:28 -07001752 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001753 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001754};
1755
1756TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001757 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1758 const VideoEncoderConfig& encoder_config) {};
1759 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001760 RunBaseTest(&test);
1761}
1762
1763TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001764 // Function for removing and recreating the send stream with a new config.
1765 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1766 const VideoEncoderConfig& encoder_config) {
eladalon413ee9a2017-08-22 04:02:52 -07001767 task_queue_.SendTask([this, &send_stream_config, &encoder_config]() {
1768 Stop();
1769 sender_call_->DestroyVideoSendStream(video_send_stream_);
1770 video_send_config_ = send_stream_config.Copy();
1771 video_encoder_config_ = encoder_config.Copy();
1772 video_send_stream_ = sender_call_->CreateVideoSendStream(
1773 video_send_config_.Copy(), video_encoder_config_.Copy());
1774 video_send_stream_->SetSource(
1775 frame_generator_capturer_.get(),
1776 VideoSendStream::DegradationPreference::kMaintainResolution);
1777 Start();
1778 });
sprangf24a0642017-02-28 13:23:26 -08001779 };
1780 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001781 RunBaseTest(&test);
1782}
1783
perkjfa10b552016-10-02 23:45:26 -07001784// This test verifies that new frame sizes reconfigures encoders even though not
1785// (yet) sending. The purpose of this is to permit encoding as quickly as
1786// possible once we start sending. Likely the frames being input are from the
1787// same source that will be sent later, which just means that we're ready
1788// earlier.
1789TEST_F(VideoSendStreamTest,
1790 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1791 class EncoderObserver : public test::FakeEncoder {
1792 public:
1793 EncoderObserver()
1794 : FakeEncoder(Clock::GetRealTimeClock()),
1795 init_encode_called_(false, false),
1796 number_of_initializations_(0),
1797 last_initialized_frame_width_(0),
1798 last_initialized_frame_height_(0) {}
1799
1800 void WaitForResolution(int width, int height) {
1801 {
1802 rtc::CritScope lock(&crit_);
1803 if (last_initialized_frame_width_ == width &&
1804 last_initialized_frame_height_ == height) {
1805 return;
1806 }
1807 }
Erik Språng08127a92016-11-16 16:41:30 +01001808 EXPECT_TRUE(
1809 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001810 {
1811 rtc::CritScope lock(&crit_);
1812 EXPECT_EQ(width, last_initialized_frame_width_);
1813 EXPECT_EQ(height, last_initialized_frame_height_);
1814 }
1815 }
1816
1817 private:
1818 int32_t InitEncode(const VideoCodec* config,
1819 int32_t number_of_cores,
1820 size_t max_payload_size) override {
1821 rtc::CritScope lock(&crit_);
1822 last_initialized_frame_width_ = config->width;
1823 last_initialized_frame_height_ = config->height;
1824 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001825 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001826 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1827 }
1828
1829 int32_t Encode(const VideoFrame& input_image,
1830 const CodecSpecificInfo* codec_specific_info,
1831 const std::vector<FrameType>* frame_types) override {
1832 ADD_FAILURE()
1833 << "Unexpected Encode call since the send stream is not started";
1834 return 0;
1835 }
1836
1837 rtc::CriticalSection crit_;
1838 rtc::Event init_encode_called_;
danilchapa37de392017-09-09 04:17:22 -07001839 size_t number_of_initializations_ RTC_GUARDED_BY(&crit_);
1840 int last_initialized_frame_width_ RTC_GUARDED_BY(&crit_);
1841 int last_initialized_frame_height_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07001842 };
1843
perkjfa10b552016-10-02 23:45:26 -07001844 test::NullTransport transport;
perkjfa10b552016-10-02 23:45:26 -07001845 EncoderObserver encoder;
eladalon413ee9a2017-08-22 04:02:52 -07001846
1847 task_queue_.SendTask([this, &transport, &encoder]() {
1848 CreateSenderCall(Call::Config(event_log_.get()));
1849 CreateSendConfig(1, 0, 0, &transport);
1850 video_send_config_.encoder_settings.encoder = &encoder;
1851 CreateVideoStreams();
1852 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1853 kDefaultHeight);
1854 frame_generator_capturer_->Start();
1855 });
perkjfa10b552016-10-02 23:45:26 -07001856
1857 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
eladalon413ee9a2017-08-22 04:02:52 -07001858
1859 task_queue_.SendTask([this]() {
1860 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1861 kDefaultHeight * 2);
1862 });
1863
perkjfa10b552016-10-02 23:45:26 -07001864 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
eladalon413ee9a2017-08-22 04:02:52 -07001865
1866 task_queue_.SendTask([this]() {
1867 DestroyStreams();
1868 DestroyCalls();
1869 });
perkjfa10b552016-10-02 23:45:26 -07001870}
1871
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001872TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1873 class StartBitrateObserver : public test::FakeEncoder {
1874 public:
1875 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001876 : FakeEncoder(Clock::GetRealTimeClock()),
1877 start_bitrate_changed_(false, false),
1878 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001879 int32_t InitEncode(const VideoCodec* config,
1880 int32_t number_of_cores,
1881 size_t max_payload_size) override {
1882 rtc::CritScope lock(&crit_);
1883 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001884 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001885 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1886 }
1887
1888 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1889 rtc::CritScope lock(&crit_);
1890 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001891 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001892 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1893 }
1894
1895 int GetStartBitrateKbps() const {
1896 rtc::CritScope lock(&crit_);
1897 return start_bitrate_kbps_;
1898 }
1899
pbos14fe7082016-04-20 06:35:56 -07001900 bool WaitForStartBitrate() {
1901 return start_bitrate_changed_.Wait(
1902 VideoSendStreamTest::kDefaultTimeoutMs);
1903 }
1904
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001905 private:
pbos5ad935c2016-01-25 03:52:44 -08001906 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001907 rtc::Event start_bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07001908 int start_bitrate_kbps_ RTC_GUARDED_BY(crit_);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001909 };
1910
philipel4fb651d2017-04-10 03:54:05 -07001911 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001912
solenberg4fbae2b2015-08-28 04:07:10 -07001913 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001914 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001915
1916 Call::Config::BitrateConfig bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07001917 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001918 sender_call_->SetBitrateConfig(bitrate_config);
1919
1920 StartBitrateObserver encoder;
stefanff483612015-12-21 03:14:00 -08001921 video_send_config_.encoder_settings.encoder = &encoder;
perkjfa10b552016-10-02 23:45:26 -07001922 // Since this test does not use a capturer, set |internal_source| = true.
1923 // Encoder configuration is otherwise updated on the next video frame.
1924 video_send_config_.encoder_settings.internal_source = true;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001925
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001926 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001927
pbos14fe7082016-04-20 06:35:56 -07001928 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07001929 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001930 encoder.GetStartBitrateKbps());
1931
perkjfa10b552016-10-02 23:45:26 -07001932 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07001933 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001934
1935 // New bitrate should be reconfigured above the previous max. As there's no
1936 // network connection this shouldn't be flaky, as no bitrate should've been
1937 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07001938 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001939 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
1940 encoder.GetStartBitrateKbps());
1941
1942 DestroyStreams();
1943}
1944
perkj57c21f92016-06-17 07:27:16 -07001945// This test that if the encoder use an internal source, VideoEncoder::SetRates
1946// will be called with zero bitrate during initialization and that
1947// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
1948// with zero bitrate.
1949TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
1950 class StartStopBitrateObserver : public test::FakeEncoder {
1951 public:
1952 StartStopBitrateObserver()
1953 : FakeEncoder(Clock::GetRealTimeClock()),
1954 encoder_init_(false, false),
Erik Språng08127a92016-11-16 16:41:30 +01001955 bitrate_changed_(false, false) {}
perkj57c21f92016-06-17 07:27:16 -07001956 int32_t InitEncode(const VideoCodec* config,
1957 int32_t number_of_cores,
1958 size_t max_payload_size) override {
1959 rtc::CritScope lock(&crit_);
perkj57c21f92016-06-17 07:27:16 -07001960 encoder_init_.Set();
1961 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1962 }
1963
Erik Språng08127a92016-11-16 16:41:30 +01001964 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
1965 uint32_t framerate) override {
perkj57c21f92016-06-17 07:27:16 -07001966 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01001967 bitrate_kbps_ = rtc::Optional<int>(bitrate.get_sum_kbps());
perkj57c21f92016-06-17 07:27:16 -07001968 bitrate_changed_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01001969 return FakeEncoder::SetRateAllocation(bitrate, framerate);
perkj57c21f92016-06-17 07:27:16 -07001970 }
1971
1972 bool WaitForEncoderInit() {
1973 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1974 }
Erik Språng08127a92016-11-16 16:41:30 +01001975
1976 bool WaitBitrateChanged(bool non_zero) {
1977 do {
1978 rtc::Optional<int> bitrate_kbps;
1979 {
1980 rtc::CritScope lock(&crit_);
1981 bitrate_kbps = bitrate_kbps_;
1982 }
1983 if (!bitrate_kbps)
1984 continue;
1985
1986 if ((non_zero && *bitrate_kbps > 0) ||
1987 (!non_zero && *bitrate_kbps == 0)) {
1988 return true;
1989 }
1990 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
1991 return false;
perkj57c21f92016-06-17 07:27:16 -07001992 }
1993
1994 private:
1995 rtc::CriticalSection crit_;
1996 rtc::Event encoder_init_;
1997 rtc::Event bitrate_changed_;
danilchapa37de392017-09-09 04:17:22 -07001998 rtc::Optional<int> bitrate_kbps_ RTC_GUARDED_BY(crit_);
perkj57c21f92016-06-17 07:27:16 -07001999 };
2000
perkj57c21f92016-06-17 07:27:16 -07002001 test::NullTransport transport;
perkj57c21f92016-06-17 07:27:16 -07002002 StartStopBitrateObserver encoder;
perkj57c21f92016-06-17 07:27:16 -07002003
eladalon413ee9a2017-08-22 04:02:52 -07002004 task_queue_.SendTask([this, &transport, &encoder]() {
2005 CreateSenderCall(Call::Config(event_log_.get()));
2006 CreateSendConfig(1, 0, 0, &transport);
2007
2008 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
2009
2010 video_send_config_.encoder_settings.encoder = &encoder;
2011 video_send_config_.encoder_settings.internal_source = true;
2012
2013 CreateVideoStreams();
2014 });
perkj57c21f92016-06-17 07:27:16 -07002015
2016 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01002017
eladalon413ee9a2017-08-22 04:02:52 -07002018 task_queue_.SendTask([this]() {
2019 video_send_stream_->Start();
2020 });
Erik Språng08127a92016-11-16 16:41:30 +01002021 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
2022
eladalon413ee9a2017-08-22 04:02:52 -07002023 task_queue_.SendTask([this]() {
2024 video_send_stream_->Stop();
2025 });
Erik Språng08127a92016-11-16 16:41:30 +01002026 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
2027
eladalon413ee9a2017-08-22 04:02:52 -07002028 task_queue_.SendTask([this]() {
2029 video_send_stream_->Start();
2030 });
Erik Språng08127a92016-11-16 16:41:30 +01002031 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07002032
eladalon413ee9a2017-08-22 04:02:52 -07002033 task_queue_.SendTask([this]() {
2034 DestroyStreams();
2035 DestroyCalls();
2036 });
perkj57c21f92016-06-17 07:27:16 -07002037}
2038
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002039TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07002040 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002041 public:
Peter Boström5811a392015-12-10 13:02:50 +01002042 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002043
nissed30a1112016-04-18 05:15:22 -07002044 void OnFrame(const VideoFrame& video_frame) override {
2045 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01002046 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002047 }
2048
2049 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01002050 const int kWaitFrameTimeoutMs = 3000;
2051 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002052 << "Timeout while waiting for output frames.";
2053 }
2054
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002055 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002056 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002057 }
2058
2059 private:
2060 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002061 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002062
2063 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01002064 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002065 };
2066
solenberg4fbae2b2015-08-28 04:07:10 -07002067 test::NullTransport transport;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002068 FrameObserver observer;
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002069 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07002070
eladalon413ee9a2017-08-22 04:02:52 -07002071 task_queue_.SendTask([this, &transport, &observer, &input_frames]() {
2072 // Initialize send stream.
2073 CreateSenderCall(Call::Config(event_log_.get()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002074
eladalon413ee9a2017-08-22 04:02:52 -07002075 CreateSendConfig(1, 0, 0, &transport);
2076 video_send_config_.pre_encode_callback = &observer;
2077 CreateVideoStreams();
2078
2079 // Prepare five input frames. Send ordinary VideoFrame and texture frames
2080 // alternatively.
2081 int width = 168;
2082 int height = 132;
2083
2084 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2085 width, height, 1, 1, kVideoRotation_0));
2086 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2087 width, height, 2, 2, kVideoRotation_0));
2088 input_frames.push_back(CreateVideoFrame(width, height, 3));
2089 input_frames.push_back(CreateVideoFrame(width, height, 4));
2090 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2091 width, height, 5, 5, kVideoRotation_0));
2092
2093 video_send_stream_->Start();
2094 test::FrameForwarder forwarder;
2095 video_send_stream_->SetSource(
2096 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
2097 for (size_t i = 0; i < input_frames.size(); i++) {
2098 forwarder.IncomingCapturedFrame(input_frames[i]);
2099 // Wait until the output frame is received before sending the next input
2100 // frame. Or the previous input frame may be replaced without delivering.
2101 observer.WaitOutputFrame();
2102 }
2103 video_send_stream_->Stop();
2104 video_send_stream_->SetSource(
2105 nullptr, VideoSendStream::DegradationPreference::kMaintainFramerate);
2106 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002107
2108 // Test if the input and output frames are the same. render_time_ms and
2109 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002110 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002111
eladalon413ee9a2017-08-22 04:02:52 -07002112 task_queue_.SendTask([this]() {
2113 DestroyStreams();
2114 DestroyCalls();
2115 });
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002116}
2117
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002118void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
2119 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002120 EXPECT_EQ(frames1.size(), frames2.size());
2121 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07002122 // Compare frame buffers, since we don't care about differing timestamps.
2123 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
2124 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002125}
2126
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002127VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002128 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002129 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002130 memset(buffer.get(), data, kSizeY);
Magnus Jedvert90e31902017-06-07 11:32:50 +02002131 VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002132 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002133 // Use data as a ms timestamp.
2134 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002135 return frame;
2136}
2137
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002138TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
2139 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2140 public:
eladalon413ee9a2017-08-22 04:02:52 -07002141 explicit EncoderStateObserver(
2142 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002143 : SendTest(kDefaultTimeoutMs),
eladalon413ee9a2017-08-22 04:02:52 -07002144 task_queue_(task_queue),
Erik Språng737336d2016-07-29 12:59:36 +02002145 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002146 initialized_(false),
2147 callback_registered_(false),
2148 num_releases_(0),
2149 released_(false) {}
2150
2151 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002152 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002153 return released_;
2154 }
2155
2156 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002157 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002158 return initialized_ && callback_registered_;
2159 }
2160
2161 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002162 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002163 return num_releases_;
2164 }
2165
2166 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002167 int32_t InitEncode(const VideoCodec* codecSettings,
2168 int32_t numberOfCores,
2169 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002170 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002171 EXPECT_FALSE(initialized_);
2172 initialized_ = true;
2173 released_ = false;
2174 return 0;
2175 }
2176
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002177 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002178 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002179 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002180 EXPECT_TRUE(IsReadyForEncode());
2181
Peter Boström5811a392015-12-10 13:02:50 +01002182 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002183 return 0;
2184 }
2185
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002186 int32_t RegisterEncodeCompleteCallback(
2187 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002188 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002189 EXPECT_TRUE(initialized_);
2190 callback_registered_ = true;
2191 return 0;
2192 }
2193
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002194 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002195 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002196 EXPECT_TRUE(IsReadyForEncode());
2197 EXPECT_FALSE(released_);
2198 initialized_ = false;
2199 callback_registered_ = false;
2200 released_ = true;
2201 ++num_releases_;
2202 return 0;
2203 }
2204
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002205 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002206 EXPECT_TRUE(IsReadyForEncode());
2207 return 0;
2208 }
2209
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002210 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002211 EXPECT_TRUE(IsReadyForEncode());
2212 return 0;
2213 }
2214
stefanff483612015-12-21 03:14:00 -08002215 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002216 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002217 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002218 stream_ = send_stream;
2219 }
2220
stefanff483612015-12-21 03:14:00 -08002221 void ModifyVideoConfigs(
2222 VideoSendStream::Config* send_config,
2223 std::vector<VideoReceiveStream::Config>* receive_configs,
2224 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002225 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07002226 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002227 }
2228
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002229 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002230 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
eladalon413ee9a2017-08-22 04:02:52 -07002231
2232 task_queue_->SendTask([this]() {
2233 EXPECT_EQ(0u, num_releases());
2234 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
2235 EXPECT_EQ(0u, num_releases());
2236 stream_->Stop();
2237 // Encoder should not be released before destroying the VideoSendStream.
2238 EXPECT_FALSE(IsReleased());
2239 EXPECT_TRUE(IsReadyForEncode());
2240 stream_->Start();
2241 });
2242
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002243 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002244 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002245 }
2246
eladalon413ee9a2017-08-22 04:02:52 -07002247 test::SingleThreadedTaskQueueForTesting* const task_queue_;
Peter Boströmf2f82832015-05-01 13:00:41 +02002248 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002249 VideoSendStream* stream_;
danilchapa37de392017-09-09 04:17:22 -07002250 bool initialized_ RTC_GUARDED_BY(crit_);
2251 bool callback_registered_ RTC_GUARDED_BY(crit_);
2252 size_t num_releases_ RTC_GUARDED_BY(crit_);
2253 bool released_ RTC_GUARDED_BY(crit_);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002254 VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002255 } test_encoder(&task_queue_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002256
stefane74eef12016-01-08 06:47:13 -08002257 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002258
2259 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002260 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002261}
2262
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002263TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2264 class VideoCodecConfigObserver : public test::SendTest,
2265 public test::FakeEncoder {
2266 public:
2267 VideoCodecConfigObserver()
2268 : SendTest(kDefaultTimeoutMs),
2269 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002270 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002271 num_initializations_(0),
2272 stream_(nullptr) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002273
2274 private:
stefanff483612015-12-21 03:14:00 -08002275 void ModifyVideoConfigs(
2276 VideoSendStream::Config* send_config,
2277 std::vector<VideoReceiveStream::Config>* receive_configs,
2278 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002279 send_config->encoder_settings.encoder = this;
sprangf24a0642017-02-28 13:23:26 -08002280 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002281 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002282 }
2283
stefanff483612015-12-21 03:14:00 -08002284 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002285 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002286 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002287 stream_ = send_stream;
2288 }
2289
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002290 int32_t InitEncode(const VideoCodec* config,
2291 int32_t number_of_cores,
2292 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002293 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002294 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002295 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002296 } else {
2297 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002298 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002299 }
2300 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002301 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002302 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2303 }
2304
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002305 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002306 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002307 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002308
sprangf24a0642017-02-28 13:23:26 -08002309 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002310 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002311 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002312 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002313 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2314 "new encoder settings.";
2315 }
2316
sprangf24a0642017-02-28 13:23:26 -08002317 const uint32_t kFirstMaxBitrateBps = 1000000;
2318 const uint32_t kSecondMaxBitrateBps = 2000000;
2319
pbos14fe7082016-04-20 06:35:56 -07002320 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002321 size_t num_initializations_;
2322 VideoSendStream* stream_;
2323 VideoEncoderConfig encoder_config_;
2324 } test;
2325
stefane74eef12016-01-08 06:47:13 -08002326 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002327}
2328
Peter Boström53eda3d2015-03-27 15:53:18 +01002329static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
2330template <typename T>
2331class VideoCodecConfigObserver : public test::SendTest,
2332 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002333 public:
2334 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2335 const char* codec_name)
2336 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2337 FakeEncoder(Clock::GetRealTimeClock()),
2338 video_codec_type_(video_codec_type),
2339 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002340 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002341 num_initializations_(0),
2342 stream_(nullptr) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002343 memset(&encoder_settings_, 0, sizeof(encoder_settings_));
2344 }
2345
2346 private:
perkjfa10b552016-10-02 23:45:26 -07002347 class VideoStreamFactory
2348 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2349 public:
2350 VideoStreamFactory() {}
2351
2352 private:
2353 std::vector<VideoStream> CreateEncoderStreams(
2354 int width,
2355 int height,
2356 const VideoEncoderConfig& encoder_config) override {
2357 std::vector<VideoStream> streams =
2358 test::CreateVideoStreams(width, height, encoder_config);
2359 for (size_t i = 0; i < streams.size(); ++i) {
2360 streams[i].temporal_layer_thresholds_bps.resize(
2361 kVideoCodecConfigObserverNumberOfTemporalLayers - 1);
2362 }
2363 return streams;
2364 }
2365 };
2366
stefanff483612015-12-21 03:14:00 -08002367 void ModifyVideoConfigs(
2368 VideoSendStream::Config* send_config,
2369 std::vector<VideoReceiveStream::Config>* receive_configs,
2370 VideoEncoderConfig* encoder_config) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002371 send_config->encoder_settings.encoder = this;
2372 send_config->encoder_settings.payload_name = codec_name_;
2373
kthelgason29a44e32016-09-27 03:52:02 -07002374 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002375 encoder_config->video_stream_factory =
2376 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002377 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002378 }
2379
stefanff483612015-12-21 03:14:00 -08002380 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002381 VideoSendStream* send_stream,
2382 const std::vector<VideoReceiveStream*>& receive_streams) override {
2383 stream_ = send_stream;
2384 }
2385
2386 int32_t InitEncode(const VideoCodec* config,
2387 int32_t number_of_cores,
2388 size_t max_payload_size) override {
2389 EXPECT_EQ(video_codec_type_, config->codecType);
2390 VerifyCodecSpecifics(*config);
2391 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002392 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002393 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2394 }
2395
2396 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002397 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2398 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002399
2400 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002401 EXPECT_TRUE(
2402 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002403 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002404
2405 encoder_settings_.frameDroppingOn = true;
kthelgason29a44e32016-09-27 03:52:02 -07002406 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002407 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002408 ASSERT_TRUE(
2409 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002410 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002411 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2412 "new encoder settings.";
2413 }
2414
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002415 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002416 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002417 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002418 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2419 return 0;
2420 }
2421
2422 T encoder_settings_;
2423 const VideoCodecType video_codec_type_;
2424 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002425 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002426 size_t num_initializations_;
2427 VideoSendStream* stream_;
2428 VideoEncoderConfig encoder_config_;
2429};
2430
2431template <>
2432void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2433 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002434 EXPECT_EQ(
2435 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002436}
kthelgason29a44e32016-09-27 03:52:02 -07002437
2438template <>
2439rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2440VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2441 return new rtc::RefCountedObject<
2442 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2443}
2444
Peter Boström53eda3d2015-03-27 15:53:18 +01002445template <>
2446void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2447 const VideoCodec& config) const {
2448 // Check that the number of temporal layers has propagated properly to
2449 // VideoCodec.
2450 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002451 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002452
2453 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2454 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2455 config.simulcastStream[i].numberOfTemporalLayers);
2456 }
2457
2458 // Set expected temporal layers as they should have been set when
Erik Språng08127a92016-11-16 16:41:30 +01002459 // reconfiguring the encoder and not match the set config. Also copy the
mflodmancc3d4422017-08-03 08:27:51 -07002460 // TemporalLayersFactory pointer that has been injected by VideoStreamEncoder.
Peter Boström53eda3d2015-03-27 15:53:18 +01002461 VideoCodecVP8 encoder_settings = encoder_settings_;
2462 encoder_settings.numberOfTemporalLayers =
2463 kVideoCodecConfigObserverNumberOfTemporalLayers;
Erik Språng08127a92016-11-16 16:41:30 +01002464 encoder_settings.tl_factory = config.VP8().tl_factory;
hta257dc392016-10-25 09:05:06 -07002465 EXPECT_EQ(
2466 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002467}
kthelgason29a44e32016-09-27 03:52:02 -07002468
2469template <>
2470rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2471VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2472 return new rtc::RefCountedObject<
2473 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2474}
2475
Peter Boström53eda3d2015-03-27 15:53:18 +01002476template <>
2477void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2478 const VideoCodec& config) const {
2479 // Check that the number of temporal layers has propagated properly to
2480 // VideoCodec.
2481 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002482 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002483
2484 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2485 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2486 config.simulcastStream[i].numberOfTemporalLayers);
2487 }
2488
2489 // Set expected temporal layers as they should have been set when
2490 // reconfiguring the encoder and not match the set config.
2491 VideoCodecVP9 encoder_settings = encoder_settings_;
2492 encoder_settings.numberOfTemporalLayers =
2493 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002494 EXPECT_EQ(
2495 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002496}
2497
kthelgason29a44e32016-09-27 03:52:02 -07002498template <>
2499rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2500VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2501 return new rtc::RefCountedObject<
2502 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2503}
2504
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002505TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002506 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002507 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002508}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002509
Peter Boström53eda3d2015-03-27 15:53:18 +01002510TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2511 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002512 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002513}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002514
Peter Boström53eda3d2015-03-27 15:53:18 +01002515TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2516 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002517 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002518}
2519
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002520TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002521 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002522 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002523 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2524 rtp_packets_sent_(0),
2525 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002526
2527 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002528 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002529 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002530 RTPHeader header;
2531 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002532 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002533 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2534 return SEND_PACKET;
2535 }
2536
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002537 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002538 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002539 test::RtcpPacketParser parser;
2540 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002541
danilchap3dc929e2016-11-02 08:21:59 -07002542 if (parser.sender_report()->num_packets() > 0) {
2543 // Only compare sent media bytes if SenderPacketCount matches the
2544 // number of sent rtp packets (a new rtp packet could be sent before
2545 // the rtcp packet).
2546 if (parser.sender_report()->sender_octet_count() > 0 &&
2547 parser.sender_report()->sender_packet_count() ==
2548 rtp_packets_sent_) {
2549 EXPECT_EQ(media_bytes_sent_,
2550 parser.sender_report()->sender_octet_count());
2551 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002552 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002553 }
2554
2555 return SEND_PACKET;
2556 }
2557
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002558 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002559 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002560 }
2561
stefan4b569042015-11-11 06:39:57 -08002562 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002563 size_t rtp_packets_sent_ RTC_GUARDED_BY(&crit_);
2564 size_t media_bytes_sent_ RTC_GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002565 } test;
2566
stefane74eef12016-01-08 06:47:13 -08002567 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002568}
2569
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002570TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
2571 static const int kScreencastTargetBitrateKbps = 200;
perkjfa10b552016-10-02 23:45:26 -07002572
2573 class VideoStreamFactory
2574 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2575 public:
2576 VideoStreamFactory() {}
2577
2578 private:
2579 std::vector<VideoStream> CreateEncoderStreams(
2580 int width,
2581 int height,
2582 const VideoEncoderConfig& encoder_config) override {
2583 std::vector<VideoStream> streams =
2584 test::CreateVideoStreams(width, height, encoder_config);
2585 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
2586 streams[0].temporal_layer_thresholds_bps.push_back(
2587 kScreencastTargetBitrateKbps * 1000);
2588 return streams;
2589 }
2590 };
2591
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002592 class ScreencastTargetBitrateTest : public test::SendTest,
2593 public test::FakeEncoder {
2594 public:
2595 ScreencastTargetBitrateTest()
2596 : SendTest(kDefaultTimeoutMs),
2597 test::FakeEncoder(Clock::GetRealTimeClock()) {}
2598
2599 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002600 int32_t InitEncode(const VideoCodec* config,
2601 int32_t number_of_cores,
2602 size_t max_payload_size) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002603 EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps),
2604 config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002605 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002606 return test::FakeEncoder::InitEncode(
2607 config, number_of_cores, max_payload_size);
2608 }
stefanff483612015-12-21 03:14:00 -08002609 void ModifyVideoConfigs(
2610 VideoSendStream::Config* send_config,
2611 std::vector<VideoReceiveStream::Config>* receive_configs,
2612 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002613 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002614 EXPECT_EQ(1u, encoder_config->number_of_streams);
2615 encoder_config->video_stream_factory =
2616 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002617 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002618 }
2619
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002620 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002621 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002622 << "Timed out while waiting for the encoder to be initialized.";
2623 }
2624 } test;
2625
stefane74eef12016-01-08 06:47:13 -08002626 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002627}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002628
philipelc6957c72016-04-28 15:52:49 +02002629TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002630 // These are chosen to be "kind of odd" to not be accidentally checked against
2631 // default values.
2632 static const int kMinBitrateKbps = 137;
2633 static const int kStartBitrateKbps = 345;
2634 static const int kLowerMaxBitrateKbps = 312;
2635 static const int kMaxBitrateKbps = 413;
2636 static const int kIncreasedStartBitrateKbps = 451;
2637 static const int kIncreasedMaxBitrateKbps = 597;
2638 class EncoderBitrateThresholdObserver : public test::SendTest,
2639 public test::FakeEncoder {
2640 public:
eladalon413ee9a2017-08-22 04:02:52 -07002641 explicit EncoderBitrateThresholdObserver(
2642 test::SingleThreadedTaskQueueForTesting* task_queue)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002643 : SendTest(kDefaultTimeoutMs),
2644 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07002645 task_queue_(task_queue),
pbos14fe7082016-04-20 06:35:56 -07002646 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002647 bitrate_changed_event_(false, false),
2648 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002649 num_initializations_(0),
2650 call_(nullptr),
2651 send_stream_(nullptr) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002652
2653 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002654 int32_t InitEncode(const VideoCodec* codecSettings,
2655 int32_t numberOfCores,
2656 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002657 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2658 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002659 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002660 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2661 codecSettings->minBitrate);
2662 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2663 codecSettings->startBitrate);
2664 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2665 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002666 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002667 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002668 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2669 codecSettings->maxBitrate);
2670 // The start bitrate should be kept (-1) and capped to the max bitrate.
2671 // Since this is not an end-to-end call no receiver should have been
2672 // returning a REMB that could lower this estimate.
2673 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002674 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002675 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2676 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002677 // The start bitrate will be whatever the rate BitRateController
2678 // has currently configured but in the span of the set max and min
2679 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002680 }
2681 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002682 init_encode_event_.Set();
2683
pbos@webrtc.org00873182014-11-25 14:03:34 +00002684 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2685 maxPayloadSize);
2686 }
2687
Erik Språng08127a92016-11-16 16:41:30 +01002688 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
2689 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002690 {
2691 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002692 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2693 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002694 }
Erik Språng08127a92016-11-16 16:41:30 +01002695 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002696 }
2697 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002698 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002699 }
2700
2701 void WaitForSetRates(uint32_t expected_bitrate) {
2702 EXPECT_TRUE(
2703 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2704 << "Timed out while waiting encoder rate to be set.";
2705 rtc::CritScope lock(&crit_);
2706 EXPECT_EQ(expected_bitrate, target_bitrate_);
2707 }
2708
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002709 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07002710 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01002711 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2712 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2713 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002714 return config;
2715 }
2716
perkjfa10b552016-10-02 23:45:26 -07002717 class VideoStreamFactory
2718 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2719 public:
2720 explicit VideoStreamFactory(int min_bitrate_bps)
2721 : min_bitrate_bps_(min_bitrate_bps) {}
2722
2723 private:
2724 std::vector<VideoStream> CreateEncoderStreams(
2725 int width,
2726 int height,
2727 const VideoEncoderConfig& encoder_config) override {
2728 std::vector<VideoStream> streams =
2729 test::CreateVideoStreams(width, height, encoder_config);
2730 streams[0].min_bitrate_bps = min_bitrate_bps_;
2731 return streams;
2732 }
2733
2734 const int min_bitrate_bps_;
2735 };
2736
stefanff483612015-12-21 03:14:00 -08002737 void ModifyVideoConfigs(
2738 VideoSendStream::Config* send_config,
2739 std::vector<VideoReceiveStream::Config>* receive_configs,
2740 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002741 send_config->encoder_settings.encoder = this;
2742 // Set bitrates lower/higher than min/max to make sure they are properly
2743 // capped.
perkjfa10b552016-10-02 23:45:26 -07002744 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2745 // Create a new StreamFactory to be able to set
2746 // |VideoStream.min_bitrate_bps|.
2747 encoder_config->video_stream_factory =
2748 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002749 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002750 }
2751
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002752 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002753 call_ = sender_call;
2754 }
2755
stefanff483612015-12-21 03:14:00 -08002756 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002757 VideoSendStream* send_stream,
2758 const std::vector<VideoReceiveStream*>& receive_streams) override {
2759 send_stream_ = send_stream;
2760 }
2761
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002762 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002763 ASSERT_TRUE(
2764 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002765 << "Timed out while waiting for encoder to be configured.";
2766 WaitForSetRates(kStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002767 Call::Config::BitrateConfig bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002768 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2769 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
eladalon413ee9a2017-08-22 04:02:52 -07002770 task_queue_->SendTask([this, &bitrate_config]() {
2771 call_->SetBitrateConfig(bitrate_config);
2772 });
perkj26091b12016-09-01 01:17:40 -07002773 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2774 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002775 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002776 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002777 ASSERT_TRUE(
2778 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002779 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002780 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002781 WaitForSetRates(kLowerMaxBitrateKbps);
2782
2783 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2784 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2785 ASSERT_TRUE(
2786 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002787 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002788 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002789 // Expected target bitrate is the start bitrate set in the call to
2790 // call_->SetBitrateConfig.
2791 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002792 }
2793
eladalon413ee9a2017-08-22 04:02:52 -07002794 test::SingleThreadedTaskQueueForTesting* const task_queue_;
pbos14fe7082016-04-20 06:35:56 -07002795 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002796 rtc::Event bitrate_changed_event_;
2797 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07002798 uint32_t target_bitrate_ RTC_GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002799
pbos@webrtc.org00873182014-11-25 14:03:34 +00002800 int num_initializations_;
2801 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002802 webrtc::VideoSendStream* send_stream_;
2803 webrtc::VideoEncoderConfig encoder_config_;
eladalon413ee9a2017-08-22 04:02:52 -07002804 } test(&task_queue_);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002805
stefane74eef12016-01-08 06:47:13 -08002806 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002807}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002808
2809TEST_F(VideoSendStreamTest, ReportsSentResolution) {
2810 static const size_t kNumStreams = 3;
2811 // Unusual resolutions to make sure that they are the ones being reported.
2812 static const struct {
2813 int width;
2814 int height;
2815 } kEncodedResolution[kNumStreams] = {
2816 {241, 181}, {300, 121}, {121, 221}};
2817 class ScreencastTargetBitrateTest : public test::SendTest,
2818 public test::FakeEncoder {
2819 public:
2820 ScreencastTargetBitrateTest()
2821 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002822 test::FakeEncoder(Clock::GetRealTimeClock()),
2823 send_stream_(nullptr) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002824
2825 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002826 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002827 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002828 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002829 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002830 specifics.codecType = kVideoCodecGeneric;
2831
2832 uint8_t buffer[16] = {0};
2833 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
2834 encoded._timeStamp = input_image.timestamp();
2835 encoded.capture_time_ms_ = input_image.render_time_ms();
2836
2837 for (size_t i = 0; i < kNumStreams; ++i) {
2838 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
2839 encoded._frameType = (*frame_types)[i];
2840 encoded._encodedWidth = kEncodedResolution[i].width;
2841 encoded._encodedHeight = kEncodedResolution[i].height;
brandtre78d2662017-01-16 05:57:16 -08002842 EncodedImageCallback* callback;
2843 {
2844 rtc::CritScope cs(&crit_sect_);
2845 callback = callback_;
2846 }
2847 RTC_DCHECK(callback);
2848 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07002849 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002850 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07002851 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002852 }
2853
Peter Boström5811a392015-12-10 13:02:50 +01002854 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002855 return 0;
2856 }
stefanff483612015-12-21 03:14:00 -08002857 void ModifyVideoConfigs(
2858 VideoSendStream::Config* send_config,
2859 std::vector<VideoReceiveStream::Config>* receive_configs,
2860 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002861 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002862 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002863 }
2864
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002865 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002866
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002867 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002868 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002869 << "Timed out while waiting for the encoder to send one frame.";
2870 VideoSendStream::Stats stats = send_stream_->GetStats();
2871
2872 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002873 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002874 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002875 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002876 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002877 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002878 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002879 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
2880 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002881 }
2882 }
2883
stefanff483612015-12-21 03:14:00 -08002884 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002885 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002886 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002887 send_stream_ = send_stream;
2888 }
2889
2890 VideoSendStream* send_stream_;
2891 } test;
2892
stefane74eef12016-01-08 06:47:13 -08002893 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002894}
philipel0f9af012015-09-01 07:01:51 -07002895
Peter Boström12996152016-05-14 02:03:18 +02002896#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01002897class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07002898 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01002899 Vp9HeaderObserver()
2900 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
philipel7fabd462015-09-03 04:42:32 -07002901 vp9_encoder_(VP9Encoder::Create()),
Åsa Perssonff24c042015-12-04 10:58:08 +01002902 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
2903 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07002904 frames_sent_(0),
2905 expected_width_(0),
2906 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07002907
stefanff483612015-12-21 03:14:00 -08002908 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07002909 VideoSendStream::Config* send_config,
2910 std::vector<VideoReceiveStream::Config>* receive_configs,
2911 VideoEncoderConfig* encoder_config) {}
2912
Åsa Perssonff24c042015-12-04 10:58:08 +01002913 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07002914
2915 private:
minyue20c84cc2017-04-10 16:57:57 -07002916 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07002917
perkjfa10b552016-10-02 23:45:26 -07002918 class VideoStreamFactory
2919 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2920 public:
2921 explicit VideoStreamFactory(size_t number_of_temporal_layers)
2922 : number_of_temporal_layers_(number_of_temporal_layers) {}
2923
2924 private:
2925 std::vector<VideoStream> CreateEncoderStreams(
2926 int width,
2927 int height,
2928 const VideoEncoderConfig& encoder_config) override {
2929 std::vector<VideoStream> streams =
2930 test::CreateVideoStreams(width, height, encoder_config);
2931 streams[0].temporal_layer_thresholds_bps.resize(
2932 number_of_temporal_layers_ - 1);
2933 return streams;
2934 }
2935
2936 const size_t number_of_temporal_layers_;
2937 };
2938
stefanff483612015-12-21 03:14:00 -08002939 void ModifyVideoConfigs(
2940 VideoSendStream::Config* send_config,
2941 std::vector<VideoReceiveStream::Config>* receive_configs,
2942 VideoEncoderConfig* encoder_config) override {
philipel7fabd462015-09-03 04:42:32 -07002943 send_config->encoder_settings.encoder = vp9_encoder_.get();
philipel0f9af012015-09-01 07:01:51 -07002944 send_config->encoder_settings.payload_name = "VP9";
2945 send_config->encoder_settings.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08002946 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07002947 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
2948 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07002949 EXPECT_EQ(1u, encoder_config->number_of_streams);
2950 encoder_config->video_stream_factory =
2951 new rtc::RefCountedObject<VideoStreamFactory>(
2952 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07002953 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07002954 }
2955
perkjfa10b552016-10-02 23:45:26 -07002956 void ModifyVideoCaptureStartResolution(int* width,
2957 int* height,
2958 int* frame_rate) override {
2959 expected_width_ = *width;
2960 expected_height_ = *height;
2961 }
2962
philipel0f9af012015-09-01 07:01:51 -07002963 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002964 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
2965 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002966 }
2967
2968 Action OnSendRtp(const uint8_t* packet, size_t length) override {
2969 RTPHeader header;
2970 EXPECT_TRUE(parser_->Parse(packet, length, &header));
2971
Åsa Perssonff24c042015-12-04 10:58:08 +01002972 EXPECT_EQ(kVp9PayloadType, header.payloadType);
2973 const uint8_t* payload = packet + header.headerLength;
2974 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07002975
Åsa Perssonff24c042015-12-04 10:58:08 +01002976 bool new_packet = packets_sent_ == 0 ||
2977 IsNewerSequenceNumber(header.sequenceNumber,
2978 last_header_.sequenceNumber);
2979 if (payload_length > 0 && new_packet) {
2980 RtpDepacketizer::ParsedPayload parsed;
2981 RtpDepacketizerVp9 depacketizer;
2982 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
2983 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
2984 // Verify common fields for all configurations.
2985 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
2986 CompareConsecutiveFrames(header, parsed.type.Video);
2987 // Verify configuration specific settings.
2988 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07002989
Åsa Perssonff24c042015-12-04 10:58:08 +01002990 ++packets_sent_;
2991 if (header.markerBit) {
2992 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002993 }
Åsa Perssonff24c042015-12-04 10:58:08 +01002994 last_header_ = header;
2995 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07002996 }
philipel0f9af012015-09-01 07:01:51 -07002997 return SEND_PACKET;
2998 }
2999
philipel7fabd462015-09-03 04:42:32 -07003000 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01003001 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
3002 if (last_vp9_.picture_id > vp9.picture_id) {
3003 return vp9.picture_id == 0; // Wrap.
3004 } else {
3005 return vp9.picture_id == last_vp9_.picture_id + 1;
3006 }
3007 }
3008
3009 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01003010 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
3011 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
3012 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
3013 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
3014 vp9.spatial_idx);
3015 }
3016
3017 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
3018 uint8_t num_layers) const {
3019 switch (num_layers) {
3020 case 0:
3021 VerifyTemporalLayerStructure0(vp9);
3022 break;
3023 case 1:
3024 VerifyTemporalLayerStructure1(vp9);
3025 break;
3026 case 2:
3027 VerifyTemporalLayerStructure2(vp9);
3028 break;
3029 case 3:
3030 VerifyTemporalLayerStructure3(vp9);
3031 break;
3032 default:
3033 RTC_NOTREACHED();
3034 }
3035 }
3036
3037 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
3038 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
3039 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
3040 EXPECT_FALSE(vp9.temporal_up_switch);
3041 }
3042
3043 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
3044 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3045 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
3046 EXPECT_FALSE(vp9.temporal_up_switch);
3047 }
3048
3049 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
3050 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3051 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
3052 EXPECT_LE(vp9.temporal_idx, 1);
3053 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
3054 if (IsNewPictureId(vp9)) {
3055 uint8_t expected_tid =
3056 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3057 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3058 }
3059 }
3060
3061 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3062 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3063 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3064 EXPECT_LE(vp9.temporal_idx, 2);
3065 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3066 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3067 switch (vp9.temporal_idx) {
3068 case 0:
3069 EXPECT_EQ(2, last_vp9_.temporal_idx);
3070 EXPECT_FALSE(vp9.temporal_up_switch);
3071 break;
3072 case 1:
3073 EXPECT_EQ(2, last_vp9_.temporal_idx);
3074 EXPECT_TRUE(vp9.temporal_up_switch);
3075 break;
3076 case 2:
3077 EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
3078 break;
3079 }
3080 }
3081 }
3082
3083 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3084 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3085 return;
3086
3087 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3088 if (vp9.temporal_idx == 0)
3089 ++expected_tl0_idx;
3090 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3091 }
3092
3093 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3094 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3095 }
3096
3097 // Flexible mode (F=1): Non-flexible mode (F=0):
3098 //
3099 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3100 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3101 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3102 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3103 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3104 // M: | EXTENDED PID | M: | EXTENDED PID |
3105 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3106 // L: | T |U| S |D| L: | T |U| S |D|
3107 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3108 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3109 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3110 // X: |EXTENDED P_DIFF| V: | SS .. |
3111 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3112 // V: | SS .. |
3113 // +-+-+-+-+-+-+-+-+
3114 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3115 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3116 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3117 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003118
3119 if (vp9_settings_.numberOfSpatialLayers > 1) {
3120 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3121 } else if (vp9_settings_.numberOfTemporalLayers > 1) {
3122 EXPECT_EQ(vp9.spatial_idx, 0);
3123 } else {
3124 EXPECT_EQ(vp9.spatial_idx, kNoSpatialIdx);
3125 }
3126
3127 if (vp9_settings_.numberOfTemporalLayers > 1) {
3128 EXPECT_LT(vp9.temporal_idx, vp9_settings_.numberOfTemporalLayers);
3129 } else if (vp9_settings_.numberOfSpatialLayers > 1) {
3130 EXPECT_EQ(vp9.temporal_idx, 0);
3131 } else {
3132 EXPECT_EQ(vp9.temporal_idx, kNoTemporalIdx);
3133 }
3134
Åsa Perssonff24c042015-12-04 10:58:08 +01003135 if (vp9.ss_data_available) // V
3136 VerifySsData(vp9);
3137
3138 if (frames_sent_ == 0)
3139 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3140
3141 if (!vp9.inter_pic_predicted) {
3142 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3143 EXPECT_FALSE(vp9.temporal_up_switch);
3144 }
3145 }
3146
3147 // Scalability structure (SS).
3148 //
3149 // +-+-+-+-+-+-+-+-+
3150 // V: | N_S |Y|G|-|-|-|
3151 // +-+-+-+-+-+-+-+-+
3152 // Y: | WIDTH | N_S + 1 times
3153 // +-+-+-+-+-+-+-+-+
3154 // | HEIGHT |
3155 // +-+-+-+-+-+-+-+-+
3156 // G: | N_G |
3157 // +-+-+-+-+-+-+-+-+
3158 // N_G: | T |U| R |-|-| N_G times
3159 // +-+-+-+-+-+-+-+-+
3160 // | P_DIFF | R times
3161 // +-+-+-+-+-+-+-+-+
3162 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3163 EXPECT_TRUE(vp9.ss_data_available); // V
3164 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3165 vp9.num_spatial_layers);
3166 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003167 int expected_width = expected_width_;
3168 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003169 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003170 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3171 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3172 expected_width /= 2;
3173 expected_height /= 2;
3174 }
3175 }
3176
3177 void CompareConsecutiveFrames(const RTPHeader& header,
3178 const RTPVideoHeader& video) const {
3179 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
3180
3181 bool new_frame = packets_sent_ == 0 ||
3182 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003183 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003184 if (!new_frame) {
3185 EXPECT_FALSE(last_header_.markerBit);
3186 EXPECT_EQ(last_header_.timestamp, header.timestamp);
3187 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
3188 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
3189 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
3190 VerifySpatialIdxWithinFrame(vp9);
3191 return;
3192 }
3193 // New frame.
3194 EXPECT_TRUE(vp9.beginning_of_frame);
3195
3196 // Compare with last packet in previous frame.
3197 if (frames_sent_ == 0)
3198 return;
3199 EXPECT_TRUE(last_vp9_.end_of_frame);
3200 EXPECT_TRUE(last_header_.markerBit);
3201 EXPECT_TRUE(ContinuousPictureId(vp9));
3202 VerifyTl0Idx(vp9);
3203 }
3204
kwiberg27f982b2016-03-01 11:52:33 -08003205 std::unique_ptr<VP9Encoder> vp9_encoder_;
philipel0f9af012015-09-01 07:01:51 -07003206 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003207 webrtc::VideoEncoderConfig encoder_config_;
3208 RTPHeader last_header_;
3209 RTPVideoHeaderVP9 last_vp9_;
3210 size_t packets_sent_;
3211 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003212 int expected_width_;
3213 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003214};
3215
Åsa Perssonff24c042015-12-04 10:58:08 +01003216TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
3217 const uint8_t kNumTemporalLayers = 1;
3218 const uint8_t kNumSpatialLayers = 1;
3219 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3220}
3221
3222TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
3223 const uint8_t kNumTemporalLayers = 2;
3224 const uint8_t kNumSpatialLayers = 1;
3225 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3226}
3227
3228TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
3229 const uint8_t kNumTemporalLayers = 3;
3230 const uint8_t kNumSpatialLayers = 1;
3231 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3232}
3233
3234TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
3235 const uint8_t kNumTemporalLayers = 1;
3236 const uint8_t kNumSpatialLayers = 2;
3237 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3238}
3239
3240TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3241 const uint8_t kNumTemporalLayers = 2;
3242 const uint8_t kNumSpatialLayers = 2;
3243 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3244}
3245
3246TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3247 const uint8_t kNumTemporalLayers = 3;
3248 const uint8_t kNumSpatialLayers = 2;
3249 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3250}
3251
3252void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3253 uint8_t num_spatial_layers) {
3254 static const size_t kNumFramesToSend = 100;
3255 // Set to < kNumFramesToSend and coprime to length of temporal layer
3256 // structures to verify temporal id reset on key frame.
3257 static const int kKeyFrameInterval = 31;
3258 class NonFlexibleMode : public Vp9HeaderObserver {
3259 public:
3260 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3261 : num_temporal_layers_(num_temporal_layers),
3262 num_spatial_layers_(num_spatial_layers),
3263 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
stefanff483612015-12-21 03:14:00 -08003264 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003265 VideoSendStream::Config* send_config,
3266 std::vector<VideoReceiveStream::Config>* receive_configs,
3267 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003268 vp9_settings_.flexibleMode = false;
3269 vp9_settings_.frameDroppingOn = false;
3270 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3271 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3272 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003273 }
3274
Åsa Perssonff24c042015-12-04 10:58:08 +01003275 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003276 bool ss_data_expected =
3277 !vp9.inter_pic_predicted && vp9.beginning_of_frame &&
3278 (vp9.spatial_idx == 0 || vp9.spatial_idx == kNoSpatialIdx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003279 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003280 if (num_spatial_layers_ > 1) {
3281 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted);
3282 } else {
3283 EXPECT_FALSE(vp9.inter_layer_predicted);
3284 }
3285
asapersson38bb8ad2015-12-14 01:41:19 -08003286 EXPECT_EQ(!vp9.inter_pic_predicted,
3287 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003288
3289 if (IsNewPictureId(vp9)) {
Sergey Silkin3f2634e2017-11-06 11:49:19 +01003290 if (num_temporal_layers_ == 1 && num_spatial_layers_ == 1) {
3291 EXPECT_EQ(kNoSpatialIdx, vp9.spatial_idx);
3292 } else {
3293 EXPECT_EQ(0, vp9.spatial_idx);
3294 }
3295 if (num_spatial_layers_ > 1)
3296 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
Åsa Perssonff24c042015-12-04 10:58:08 +01003297 }
3298
3299 VerifyFixedTemporalLayerStructure(vp9,
3300 l_field_ ? num_temporal_layers_ : 0);
3301
3302 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003303 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003304 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003305 const uint8_t num_temporal_layers_;
3306 const uint8_t num_spatial_layers_;
3307 const bool l_field_;
3308 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003309
stefane74eef12016-01-08 06:47:13 -08003310 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003311}
3312
asaperssond9f641e2016-01-21 01:11:35 -08003313TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3314 static const size_t kNumFramesToSend = 50;
3315 static const int kWidth = 4;
3316 static const int kHeight = 4;
3317 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3318 void ModifyVideoConfigsHook(
3319 VideoSendStream::Config* send_config,
3320 std::vector<VideoReceiveStream::Config>* receive_configs,
3321 VideoEncoderConfig* encoder_config) override {
3322 vp9_settings_.flexibleMode = false;
3323 vp9_settings_.numberOfTemporalLayers = 1;
3324 vp9_settings_.numberOfSpatialLayers = 1;
3325
perkjfa10b552016-10-02 23:45:26 -07003326 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003327 }
3328
3329 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3330 if (frames_sent_ > kNumFramesToSend)
3331 observation_complete_.Set();
3332 }
perkjfa10b552016-10-02 23:45:26 -07003333
3334 void ModifyVideoCaptureStartResolution(int* width,
3335 int* height,
3336 int* frame_rate) override {
3337 expected_width_ = kWidth;
3338 expected_height_ = kHeight;
3339 *width = kWidth;
3340 *height = kHeight;
3341 }
asaperssond9f641e2016-01-21 01:11:35 -08003342 } test;
3343
3344 RunBaseTest(&test);
3345}
3346
kjellanderf9e2a362017-03-24 12:17:33 -07003347#if defined(WEBRTC_ANDROID)
3348// Crashes on Android; bugs.webrtc.org/7401
3349#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3350#else
3351#define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
3352#endif
3353TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003354 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003355 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003356 VideoSendStream::Config* send_config,
3357 std::vector<VideoReceiveStream::Config>* receive_configs,
3358 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003359 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003360 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003361 vp9_settings_.numberOfTemporalLayers = 1;
3362 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003363 }
3364
Åsa Perssonff24c042015-12-04 10:58:08 +01003365 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3366 EXPECT_TRUE(vp9_header.flexible_mode);
3367 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3368 if (vp9_header.inter_pic_predicted) {
3369 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003370 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003371 }
3372 }
3373 } test;
3374
stefane74eef12016-01-08 06:47:13 -08003375 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003376}
Peter Boström12996152016-05-14 02:03:18 +02003377#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003378
perkj803d97f2016-11-01 11:45:46 -07003379void VideoSendStreamTest::TestRequestSourceRotateVideo(
3380 bool support_orientation_ext) {
philipel4fb651d2017-04-10 03:54:05 -07003381 CreateSenderCall(Call::Config(event_log_.get()));
perkj803d97f2016-11-01 11:45:46 -07003382
3383 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003384 CreateSendConfig(1, 0, 0, &transport);
perkj803d97f2016-11-01 11:45:46 -07003385 video_send_config_.rtp.extensions.clear();
3386 if (support_orientation_ext) {
3387 video_send_config_.rtp.extensions.push_back(
3388 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3389 }
3390
3391 CreateVideoStreams();
3392 test::FrameForwarder forwarder;
3393 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07003394 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
perkj803d97f2016-11-01 11:45:46 -07003395
3396 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3397 support_orientation_ext);
3398
3399 DestroyStreams();
3400}
3401
3402TEST_F(VideoSendStreamTest,
3403 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3404 TestRequestSourceRotateVideo(false);
3405}
3406
3407TEST_F(VideoSendStreamTest,
3408 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3409 TestRequestSourceRotateVideo(true);
3410}
3411
michaelta3328772016-11-29 09:25:03 -08003412// This test verifies that overhead is removed from the bandwidth estimate by
3413// testing that the maximum possible target payload rate is smaller than the
3414// maximum bandwidth estimate by the overhead rate.
michaelt273f31b2017-02-08 08:21:52 -08003415TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003416 test::ScopedFieldTrials override_field_trials(
3417 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3418 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3419 public test::FakeEncoder {
3420 public:
eladalon413ee9a2017-08-22 04:02:52 -07003421 explicit RemoveOverheadFromBandwidthTest(
3422 test::SingleThreadedTaskQueueForTesting* task_queue)
michaelta3328772016-11-29 09:25:03 -08003423 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3424 FakeEncoder(Clock::GetRealTimeClock()),
eladalon413ee9a2017-08-22 04:02:52 -07003425 task_queue_(task_queue),
michaelta3328772016-11-29 09:25:03 -08003426 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003427 max_bitrate_bps_(0),
3428 first_packet_sent_(false),
3429 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003430
3431 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
3432 uint32_t frameRate) override {
3433 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003434 // Wait for the first sent packet so that videosendstream knows
3435 // rtp_overhead.
3436 if (first_packet_sent_) {
3437 max_bitrate_bps_ = bitrate.get_sum_bps();
3438 bitrate_changed_event_.Set();
3439 }
michaelta3328772016-11-29 09:25:03 -08003440 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3441 }
3442
3443 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3444 call_ = sender_call;
3445 }
3446
3447 void ModifyVideoConfigs(
3448 VideoSendStream::Config* send_config,
3449 std::vector<VideoReceiveStream::Config>* receive_configs,
3450 VideoEncoderConfig* encoder_config) override {
3451 send_config->rtp.max_packet_size = 1200;
3452 send_config->encoder_settings.encoder = this;
3453 EXPECT_FALSE(send_config->rtp.extensions.empty());
3454 }
3455
michaelt192132e2017-01-26 09:05:27 -08003456 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3457 rtc::CritScope lock(&crit_);
3458 first_packet_sent_ = true;
3459 return SEND_PACKET;
3460 }
3461
michaelta3328772016-11-29 09:25:03 -08003462 void PerformTest() override {
michaelta3328772016-11-29 09:25:03 -08003463 Call::Config::BitrateConfig bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003464 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003465 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003466 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003467 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3468 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003469 bitrate_config.min_bitrate_bps = kMinBitrateBps;
eladalon413ee9a2017-08-22 04:02:52 -07003470 task_queue_->SendTask([this, &bitrate_config]() {
3471 call_->SetBitrateConfig(bitrate_config);
3472 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
3473 });
michaelta3328772016-11-29 09:25:03 -08003474
3475 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003476 // overhead of 40B per packet video produces 2240bps overhead.
3477 // So the encoder BW should be set to 57760bps.
3478 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
michaelta3328772016-11-29 09:25:03 -08003479 {
3480 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003481 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003482 }
3483 }
3484
3485 private:
eladalon413ee9a2017-08-22 04:02:52 -07003486 test::SingleThreadedTaskQueueForTesting* const task_queue_;
michaelta3328772016-11-29 09:25:03 -08003487 Call* call_;
3488 rtc::CriticalSection crit_;
danilchapa37de392017-09-09 04:17:22 -07003489 uint32_t max_bitrate_bps_ RTC_GUARDED_BY(&crit_);
3490 bool first_packet_sent_ RTC_GUARDED_BY(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003491 rtc::Event bitrate_changed_event_;
eladalon413ee9a2017-08-22 04:02:52 -07003492 } test(&task_queue_);
michaelta3328772016-11-29 09:25:03 -08003493 RunBaseTest(&test);
3494}
3495
sprang168794c2017-07-06 04:38:06 -07003496TEST_F(VideoSendStreamTest, SendsKeepAlive) {
3497 const int kTimeoutMs = 50; // Really short timeout for testing.
sprang168794c2017-07-06 04:38:06 -07003498
3499 class KeepaliveObserver : public test::SendTest {
3500 public:
3501 KeepaliveObserver() : SendTest(kDefaultTimeoutMs) {}
3502
sprangdb2a9fc2017-08-09 06:42:32 -07003503 void OnRtpTransportControllerSendCreated(
3504 RtpTransportControllerSend* controller) override {
3505 RtpKeepAliveConfig config;
3506 config.timeout_interval_ms = kTimeoutMs;
3507 config.payload_type = CallTest::kDefaultKeepalivePayloadType;
3508 controller->SetKeepAliveConfig(config);
sprange5c4a812017-07-11 03:44:17 -07003509 }
3510
sprang168794c2017-07-06 04:38:06 -07003511 private:
3512 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3513 RTPHeader header;
3514 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3515
sprangd2702ef2017-07-10 08:41:10 -07003516 if (header.payloadType != CallTest::kDefaultKeepalivePayloadType) {
sprang168794c2017-07-06 04:38:06 -07003517 // The video stream has started. Stop it now.
3518 if (capturer_)
3519 capturer_->Stop();
3520 } else {
3521 observation_complete_.Set();
3522 }
3523
3524 return SEND_PACKET;
3525 }
3526
sprang168794c2017-07-06 04:38:06 -07003527 void PerformTest() override {
3528 EXPECT_TRUE(Wait()) << "Timed out while waiting for keep-alive packet.";
3529 }
3530
3531 void OnFrameGeneratorCapturerCreated(
3532 test::FrameGeneratorCapturer* frame_generator_capturer) override {
3533 capturer_ = frame_generator_capturer;
3534 }
3535
3536 test::FrameGeneratorCapturer* capturer_ = nullptr;
3537 } test;
3538
3539 RunBaseTest(&test);
3540}
3541
Erik Språng7c8cca32017-10-24 17:05:18 +02003542TEST_F(VideoSendStreamTest, ConfiguresAlrWhenSendSideOn) {
3543 const std::string kAlrProbingExperiment =
3544 std::string(AlrDetector::kScreenshareProbingBweExperimentName) +
3545 "/1.1,2875,85,20,-20,0/";
3546 test::ScopedFieldTrials alr_experiment(kAlrProbingExperiment);
3547 class PacingFactorObserver : public test::SendTest {
3548 public:
3549 PacingFactorObserver(bool configure_send_side, float expected_pacing_factor)
3550 : test::SendTest(kDefaultTimeoutMs),
3551 configure_send_side_(configure_send_side),
3552 expected_pacing_factor_(expected_pacing_factor),
3553 paced_sender_(nullptr) {}
3554
3555 void ModifyVideoConfigs(
3556 VideoSendStream::Config* send_config,
3557 std::vector<VideoReceiveStream::Config>* receive_configs,
3558 VideoEncoderConfig* encoder_config) override {
3559 // Check if send-side bwe extension is already present, and remove it if
3560 // it is not desired.
3561 bool has_send_side = false;
3562 for (auto it = send_config->rtp.extensions.begin();
3563 it != send_config->rtp.extensions.end(); ++it) {
3564 if (it->uri == RtpExtension::kTransportSequenceNumberUri) {
3565 if (configure_send_side_) {
3566 has_send_side = true;
3567 } else {
3568 send_config->rtp.extensions.erase(it);
3569 }
3570 break;
3571 }
3572 }
3573
3574 if (configure_send_side_ && !has_send_side) {
3575 // Want send side, not present by default, so add it.
3576 send_config->rtp.extensions.emplace_back(
3577 RtpExtension::kTransportSequenceNumberUri,
3578 RtpExtension::kTransportSequenceNumberDefaultId);
3579 }
3580
3581 // ALR only enabled for screenshare.
3582 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
3583 }
3584
3585 void OnRtpTransportControllerSendCreated(
3586 RtpTransportControllerSend* controller) override {
3587 // Grab a reference to the pacer.
3588 paced_sender_ = controller->pacer();
3589 }
3590
3591 void OnVideoStreamsCreated(
3592 VideoSendStream* send_stream,
3593 const std::vector<VideoReceiveStream*>& receive_streams) override {
3594 // Video streams created, check that pacer is correctly configured.
3595 EXPECT_EQ(expected_pacing_factor_, paced_sender_->GetPacingFactor());
3596 observation_complete_.Set();
3597 }
3598
3599 void PerformTest() override {
3600 EXPECT_TRUE(Wait()) << "Timed out while waiting for pacer config.";
3601 }
3602
3603 private:
3604 const bool configure_send_side_;
3605 const float expected_pacing_factor_;
3606 const PacedSender* paced_sender_;
3607 };
3608
3609 // Send-side bwe on, use pacing factor from |kAlrProbingExperiment| above.
3610 PacingFactorObserver test_with_send_side(true, 1.1f);
3611 RunBaseTest(&test_with_send_side);
3612
3613 // Send-side bwe off, use default pacing factor.
3614 PacingFactorObserver test_without_send_side(
3615 false, PacedSender::kDefaultPaceMultiplier);
3616 RunBaseTest(&test_without_send_side);
3617}
3618
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003619} // namespace webrtc