blob: 37a0249e377e1066a5cc8f3266be39b2ec329457 [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
Per9b3f56e2015-04-09 13:44:16 +020014#include "webrtc/base/bind.h"
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +000015#include "webrtc/base/checks.h"
Peter Boströmff019b02015-04-30 14:16:07 +020016#include "webrtc/base/criticalsection.h"
Peter Boström5811a392015-12-10 13:02:50 +010017#include "webrtc/base/event.h"
Peter Boström415d2cd2015-10-26 11:35:17 +010018#include "webrtc/base/logging.h"
pbos12411ef2015-11-23 14:47:56 -080019#include "webrtc/base/platform_thread.h"
Erik Språng737336d2016-07-29 12:59:36 +020020#include "webrtc/base/rate_limiter.h"
nissef93752a2017-05-10 05:25:59 -070021#include "webrtc/base/timeutils.h"
ossuf515ab82016-12-07 04:52:58 -080022#include "webrtc/call/call.h"
pbosa96b60b2016-04-18 21:12:48 -070023#include "webrtc/common_video/include/frame_callback.h"
nisseea3a7982017-05-15 02:42:11 -070024#include "webrtc/common_video/include/video_frame.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010025#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
26#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +000027#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
philipel0f9af012015-09-01 07:01:51 -070028#include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h"
magjed509e4fe2016-11-18 01:34:11 -080029#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
philipel7fabd462015-09-03 04:42:32 -070030#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010031#include "webrtc/system_wrappers/include/sleep.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000032#include "webrtc/test/call_test.h"
pbos@webrtc.org709e2972014-03-19 10:59:52 +000033#include "webrtc/test/configurable_frame_size_encoder.h"
Peter Boströmeb66e802015-06-05 11:08:03 +020034#include "webrtc/test/fake_texture_frame.h"
perkja49cbd32016-09-16 07:53:41 -070035#include "webrtc/test/frame_generator.h"
nisse26acec42016-04-15 03:43:39 -070036#include "webrtc/test/frame_utils.h"
kwibergac9f8762016-09-30 22:29:43 -070037#include "webrtc/test/gtest.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000038#include "webrtc/test/null_transport.h"
danilchap3dc929e2016-11-02 08:21:59 -070039#include "webrtc/test/rtcp_packet_parser.h"
pbos@webrtc.org709e2972014-03-19 10:59:52 +000040#include "webrtc/test/testsupport/perf_test.h"
michaelta3328772016-11-29 09:25:03 -080041#include "webrtc/test/field_trial.h"
perkjfa10b552016-10-02 23:45:26 -070042
pbos@webrtc.org273a4142014-12-01 15:23:21 +000043#include "webrtc/video/send_statistics_proxy.h"
charujainbf6a45b2016-11-03 04:21:42 -070044#include "webrtc/video/transport_adapter.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000045#include "webrtc/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000046
47namespace webrtc {
48
sprang@webrtc.org346094c2014-02-18 08:40:33 +000049enum VideoFormat { kGeneric, kVP8, };
50
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070051void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
52 const std::vector<VideoFrame>& frames2);
53VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000054
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000055class VideoSendStreamTest : public test::CallTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000056 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000057 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000058 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000059 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010060
61 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
62 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -070063
64 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000065};
66
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000067TEST_F(VideoSendStreamTest, CanStartStartedStream) {
philipel4fb651d2017-04-10 03:54:05 -070068 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000069
solenberg4fbae2b2015-08-28 04:07:10 -070070 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -080071 CreateSendConfig(1, 0, 0, &transport);
Stefan Holmer9fea80f2016-01-07 17:43:18 +010072 CreateVideoStreams();
stefanff483612015-12-21 03:14:00 -080073 video_send_stream_->Start();
74 video_send_stream_->Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000075 DestroyStreams();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000076}
77
78TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
philipel4fb651d2017-04-10 03:54:05 -070079 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000080
solenberg4fbae2b2015-08-28 04:07:10 -070081 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -080082 CreateSendConfig(1, 0, 0, &transport);
Stefan Holmer9fea80f2016-01-07 17:43:18 +010083 CreateVideoStreams();
stefanff483612015-12-21 03:14:00 -080084 video_send_stream_->Stop();
85 video_send_stream_->Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000086 DestroyStreams();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000087}
88
pbos@webrtc.org013d9942013-08-22 09:42:17 +000089TEST_F(VideoSendStreamTest, SupportsCName) {
90 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000091 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000092 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000093 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +000094
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000095 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000096 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -070097 test::RtcpPacketParser parser;
98 EXPECT_TRUE(parser.Parse(packet, length));
99 if (parser.sdes()->num_packets() > 0) {
100 EXPECT_EQ(1u, parser.sdes()->chunks().size());
101 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000102
danilchap3dc929e2016-11-02 08:21:59 -0700103 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000104 }
105
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000106 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000107 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000108
stefanff483612015-12-21 03:14:00 -0800109 void ModifyVideoConfigs(
110 VideoSendStream::Config* send_config,
111 std::vector<VideoReceiveStream::Config>* receive_configs,
112 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000113 send_config->rtp.c_name = kCName;
114 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000115
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000116 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100117 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000118 }
119 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000120
stefane74eef12016-01-08 06:47:13 -0800121 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000122}
123
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000124TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000125 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000126 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000127 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000128 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100129 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000130 }
131
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000132 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000133 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000134 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000135
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000136 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
137 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
138 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700139 if (header.extension.absoluteSendTime != 0) {
140 // Wait for at least one packet with a non-zero send time. The send time
141 // is a 16-bit value derived from the system clock, and it is valid
142 // for a packet to have a zero send time. To tell that from an
143 // unpopulated value we'll wait for a packet with non-zero send time.
144 observation_complete_.Set();
145 } else {
146 LOG(LS_WARNING) << "Got a packet with zero absoluteSendTime, waiting"
147 " for another packet...";
148 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000149
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000150 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000151 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000152
stefanff483612015-12-21 03:14:00 -0800153 void ModifyVideoConfigs(
154 VideoSendStream::Config* send_config,
155 std::vector<VideoReceiveStream::Config>* receive_configs,
156 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200157 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100158 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700159 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000160 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000161
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000162 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100163 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000164 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000165 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000166
stefane74eef12016-01-08 06:47:13 -0800167 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000168}
169
pbos@webrtc.org29023282013-09-11 10:14:56 +0000170TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000171 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000172 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000173 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000174 TransmissionTimeOffsetObserver()
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000175 : SendTest(kDefaultTimeoutMs),
176 encoder_(Clock::GetRealTimeClock(), kEncodeDelayMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000177 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100178 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000179 }
180
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000181 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000182 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000183 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000184 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000185
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000186 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
187 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000188 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000189 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100190 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000191
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000192 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000193 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000194
stefanff483612015-12-21 03:14:00 -0800195 void ModifyVideoConfigs(
196 VideoSendStream::Config* send_config,
197 std::vector<VideoReceiveStream::Config>* receive_configs,
198 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000199 send_config->encoder_settings.encoder = &encoder_;
Stefan Holmer12952972015-10-29 15:13:24 +0100200 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700201 send_config->rtp.extensions.push_back(RtpExtension(
202 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000203 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000204
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000205 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100206 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000207 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000208
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000209 test::DelayedEncoder encoder_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000210 } test;
211
stefane74eef12016-01-08 06:47:13 -0800212 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000213}
214
sprang867fb522015-08-03 04:38:41 -0700215TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700216 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700217 class TransportWideSequenceNumberObserver : public test::SendTest {
218 public:
219 TransportWideSequenceNumberObserver()
220 : SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) {
221 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
222 kRtpExtensionTransportSequenceNumber, kExtensionId));
223 }
224
225 private:
226 Action OnSendRtp(const uint8_t* packet, size_t length) override {
227 RTPHeader header;
228 EXPECT_TRUE(parser_->Parse(packet, length, &header));
229
230 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
231 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
232 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
233
Peter Boström5811a392015-12-10 13:02:50 +0100234 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700235
236 return SEND_PACKET;
237 }
238
stefanff483612015-12-21 03:14:00 -0800239 void ModifyVideoConfigs(
240 VideoSendStream::Config* send_config,
241 std::vector<VideoReceiveStream::Config>* receive_configs,
242 VideoEncoderConfig* encoder_config) override {
sprang867fb522015-08-03 04:38:41 -0700243 send_config->encoder_settings.encoder = &encoder_;
sprang867fb522015-08-03 04:38:41 -0700244 }
245
246 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100247 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700248 }
249
250 test::FakeEncoder encoder_;
251 } test;
252
stefane74eef12016-01-08 06:47:13 -0800253 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700254}
255
perkj803d97f2016-11-01 11:45:46 -0700256TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
257 class VideoRotationObserver : public test::SendTest {
258 public:
259 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
260 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
261 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
262 }
263
264 Action OnSendRtp(const uint8_t* packet, size_t length) override {
265 RTPHeader header;
266 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700267 // Only the last packet of the frame is required to have the extension.
268 if (!header.markerBit)
269 return SEND_PACKET;
perkj803d97f2016-11-01 11:45:46 -0700270 EXPECT_TRUE(header.extension.hasVideoRotation);
271 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
272 observation_complete_.Set();
273 return SEND_PACKET;
274 }
275
276 void ModifyVideoConfigs(
277 VideoSendStream::Config* send_config,
278 std::vector<VideoReceiveStream::Config>* receive_configs,
279 VideoEncoderConfig* encoder_config) override {
280 send_config->rtp.extensions.clear();
281 send_config->rtp.extensions.push_back(RtpExtension(
282 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
283 }
284
285 void OnFrameGeneratorCapturerCreated(
286 test::FrameGeneratorCapturer* frame_generator_capturer) override {
287 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
288 }
289
290 void PerformTest() override {
291 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
292 }
293 } test;
294
295 RunBaseTest(&test);
296}
297
ilnik00d802b2017-04-11 10:34:31 -0700298TEST_F(VideoSendStreamTest, SupportsVideoContentType) {
ilnik10894992017-06-21 08:23:19 -0700299 class VideoContentTypeObserver : public test::SendTest {
ilnik00d802b2017-04-11 10:34:31 -0700300 public:
ilnik10894992017-06-21 08:23:19 -0700301 VideoContentTypeObserver() : SendTest(kDefaultTimeoutMs) {
ilnik00d802b2017-04-11 10:34:31 -0700302 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
303 kRtpExtensionVideoContentType, test::kVideoContentTypeExtensionId));
304 }
305
306 Action OnSendRtp(const uint8_t* packet, size_t length) override {
307 RTPHeader header;
308 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik7a3006b2017-05-23 09:34:21 -0700309 // Only the last packet of the frame must have extension.
310 if (!header.markerBit)
311 return SEND_PACKET;
ilnik00d802b2017-04-11 10:34:31 -0700312 EXPECT_TRUE(header.extension.hasVideoContentType);
313 EXPECT_EQ(VideoContentType::SCREENSHARE,
314 header.extension.videoContentType);
315 observation_complete_.Set();
316 return SEND_PACKET;
317 }
318
319 void ModifyVideoConfigs(
320 VideoSendStream::Config* send_config,
321 std::vector<VideoReceiveStream::Config>* receive_configs,
322 VideoEncoderConfig* encoder_config) override {
323 send_config->rtp.extensions.clear();
324 send_config->rtp.extensions.push_back(
325 RtpExtension(RtpExtension::kVideoContentTypeUri,
326 test::kVideoContentTypeExtensionId));
327 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
328 }
329
330 void PerformTest() override {
331 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
332 }
333 } test;
334
ilnikcf705c52017-06-08 06:18:53 -0700335 test::ScopedFieldTrials override_field_trials(
336 "WebRTC-VideoContentTypeExtension/Enabled/");
ilnik00d802b2017-04-11 10:34:31 -0700337 RunBaseTest(&test);
338}
339
ilnik04f4d122017-06-19 07:18:55 -0700340TEST_F(VideoSendStreamTest, SupportsVideoTimingFrames) {
ilnik10894992017-06-21 08:23:19 -0700341 class VideoTimingObserver : public test::SendTest {
ilnik04f4d122017-06-19 07:18:55 -0700342 public:
ilnik10894992017-06-21 08:23:19 -0700343 VideoTimingObserver() : SendTest(kDefaultTimeoutMs) {
ilnik04f4d122017-06-19 07:18:55 -0700344 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
345 kRtpExtensionVideoTiming, test::kVideoTimingExtensionId));
346 }
347
348 Action OnSendRtp(const uint8_t* packet, size_t length) override {
349 RTPHeader header;
350 EXPECT_TRUE(parser_->Parse(packet, length, &header));
ilnik10894992017-06-21 08:23:19 -0700351 // Only the last packet of the frame must have extension.
352 if (!header.markerBit)
353 return SEND_PACKET;
354 EXPECT_TRUE(header.extension.has_video_timing);
355 observation_complete_.Set();
ilnik04f4d122017-06-19 07:18:55 -0700356 return SEND_PACKET;
357 }
358
359 void ModifyVideoConfigs(
360 VideoSendStream::Config* send_config,
361 std::vector<VideoReceiveStream::Config>* receive_configs,
362 VideoEncoderConfig* encoder_config) override {
363 send_config->rtp.extensions.clear();
364 send_config->rtp.extensions.push_back(RtpExtension(
365 RtpExtension::kVideoTimingUri, test::kVideoTimingExtensionId));
366 }
367
368 void PerformTest() override {
369 EXPECT_TRUE(Wait()) << "Timed out while waiting for timing frames.";
370 }
371 } test;
372
373 RunBaseTest(&test);
374}
375
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000376class FakeReceiveStatistics : public NullReceiveStatistics {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000377 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000378 FakeReceiveStatistics(uint32_t send_ssrc,
379 uint32_t last_sequence_number,
380 uint32_t cumulative_lost,
381 uint8_t fraction_lost)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000382 : lossy_stats_(new LossyStatistician(last_sequence_number,
383 cumulative_lost,
384 fraction_lost)) {
385 stats_map_[send_ssrc] = lossy_stats_.get();
386 }
387
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000388 StatisticianMap GetActiveStatisticians() const override { return stats_map_; }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000389
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000390 StreamStatistician* GetStatistician(uint32_t ssrc) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000391 return lossy_stats_.get();
392 }
393
394 private:
395 class LossyStatistician : public StreamStatistician {
396 public:
397 LossyStatistician(uint32_t extended_max_sequence_number,
398 uint32_t cumulative_lost,
399 uint8_t fraction_lost) {
400 stats_.fraction_lost = fraction_lost;
401 stats_.cumulative_lost = cumulative_lost;
402 stats_.extended_max_sequence_number = extended_max_sequence_number;
403 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000404 bool GetStatistics(RtcpStatistics* statistics, bool reset) override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000405 *statistics = stats_;
406 return true;
407 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000408 void GetDataCounters(size_t* bytes_received,
409 uint32_t* packets_received) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000410 *bytes_received = 0;
411 *packets_received = 0;
412 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000413 void GetReceiveStreamDataCounters(
414 StreamDataCounters* data_counters) const override {}
415 uint32_t BitrateReceived() const override { return 0; }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000416 bool IsRetransmitOfOldPacket(const RTPHeader& header,
417 int64_t min_rtt) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000418 return false;
419 }
420
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000421 bool IsPacketInOrder(uint16_t sequence_number) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000422 return true;
423 }
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000424
425 RtcpStatistics stats_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000426 };
427
kwiberg27f982b2016-03-01 11:52:33 -0800428 std::unique_ptr<LossyStatistician> lossy_stats_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000429 StatisticianMap stats_map_;
430};
431
brandtre602f0a2016-10-31 03:40:49 -0700432class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100433 public:
brandtre602f0a2016-10-31 03:40:49 -0700434 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800435 bool use_nack,
436 bool expect_red,
437 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800438 const std::string& codec,
439 VideoEncoder* encoder)
brandtr20d45472017-01-02 00:34:27 -0800440 : EndToEndTest(kTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800441 encoder_(encoder),
Peter Boström39593972016-02-15 11:27:15 +0100442 payload_name_(codec),
443 use_nack_(use_nack),
444 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700445 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800446 sent_media_(false),
447 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800448 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100449
brandtr20d45472017-01-02 00:34:27 -0800450 // Some of the test cases are expected to time out and thus we are using
451 // a shorter timeout window than the default here.
452 static constexpr size_t kTimeoutMs = 10000;
453
Stefan Holmer4654d202015-12-08 09:10:43 +0100454 private:
455 Action OnSendRtp(const uint8_t* packet, size_t length) override {
456 RTPHeader header;
457 EXPECT_TRUE(parser_->Parse(packet, length, &header));
458
Stefan Holmer4654d202015-12-08 09:10:43 +0100459 int encapsulated_payload_type = -1;
460 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100461 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100462 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
463 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100464 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100465 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
466 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100467 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100468 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100469 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
470 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100471 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
472 length) {
473 // Not padding-only, media received outside of RED.
474 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800475 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100476 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100477 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000478
Stefan Holmer4654d202015-12-08 09:10:43 +0100479 if (header_extensions_enabled_) {
480 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
481 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
482 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
483 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
484 // 24 bits wrap.
485 EXPECT_GT(prev_header_.extension.absoluteSendTime,
486 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000487 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100488 EXPECT_GE(header.extension.absoluteSendTime,
489 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200490 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100491 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
492 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
493 prev_header_.extension.transportSequenceNumber;
494 EXPECT_EQ(1, seq_num_diff);
495 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200496
Stefan Holmer4654d202015-12-08 09:10:43 +0100497 if (encapsulated_payload_type != -1) {
498 if (encapsulated_payload_type ==
499 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700500 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800501 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100502 } else {
brandtr65a1e772016-12-12 01:54:58 -0800503 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000504 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000505 }
506
brandtr20d45472017-01-02 00:34:27 -0800507 if (sent_media_ && sent_ulpfec_) {
508 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100509 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000510
Stefan Holmer4654d202015-12-08 09:10:43 +0100511 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000512
Stefan Holmer4654d202015-12-08 09:10:43 +0100513 return SEND_PACKET;
514 }
515
Peter Boström39593972016-02-15 11:27:15 +0100516 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
517 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
518 // Configure some network delay.
519 const int kNetworkDelayMs = 100;
520 FakeNetworkPipe::Config config;
brandtr65a1e772016-12-12 01:54:58 -0800521 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100522 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700523 return new test::PacketTransport(
524 sender_call, this, test::PacketTransport::kSender,
525 VideoSendStreamTest::payload_type_map_, config);
Peter Boström39593972016-02-15 11:27:15 +0100526 }
527
stefanff483612015-12-21 03:14:00 -0800528 void ModifyVideoConfigs(
529 VideoSendStream::Config* send_config,
530 std::vector<VideoReceiveStream::Config>* receive_configs,
531 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100532 if (use_nack_) {
533 send_config->rtp.nack.rtp_history_ms =
534 (*receive_configs)[0].rtp.nack.rtp_history_ms =
535 VideoSendStreamTest::kNackRtpHistoryMs;
536 }
brandtr696c9c62016-12-19 05:47:28 -0800537 send_config->encoder_settings.encoder = encoder_;
Peter Boström39593972016-02-15 11:27:15 +0100538 send_config->encoder_settings.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700539 send_config->rtp.ulpfec.red_payload_type =
540 VideoSendStreamTest::kRedPayloadType;
541 send_config->rtp.ulpfec.ulpfec_payload_type =
542 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800543 EXPECT_FALSE(send_config->rtp.extensions.empty());
544 if (!header_extensions_enabled_) {
545 send_config->rtp.extensions.clear();
546 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100547 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700548 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100549 }
brandtrb5f2c3f2016-10-04 23:28:39 -0700550 (*receive_configs)[0].rtp.ulpfec.red_payload_type =
551 send_config->rtp.ulpfec.red_payload_type;
552 (*receive_configs)[0].rtp.ulpfec.ulpfec_payload_type =
553 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100554 }
555
556 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800557 EXPECT_EQ(expect_ulpfec_, Wait())
558 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100559 }
560
brandtr696c9c62016-12-19 05:47:28 -0800561 VideoEncoder* const encoder_;
562 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100563 const bool use_nack_;
564 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700565 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800566 bool sent_media_;
567 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100568 bool header_extensions_enabled_;
569 RTPHeader prev_header_;
570};
571
brandtre602f0a2016-10-31 03:40:49 -0700572TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800573 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
574 UlpfecObserver test(true, false, true, true, "VP8", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800575 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100576}
577
brandtre602f0a2016-10-31 03:40:49 -0700578TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800579 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
580 UlpfecObserver test(false, false, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100581 RunBaseTest(&test);
582}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000583
Peter Boström39593972016-02-15 11:27:15 +0100584// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
585// since we'll still have to re-request FEC packets, effectively wasting
586// bandwidth since the receiver has to wait for FEC retransmissions to determine
587// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700588TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800589 std::unique_ptr<VideoEncoder> encoder(
590 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
591 UlpfecObserver test(false, true, true, false, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100592 RunBaseTest(&test);
593}
594
595// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800596TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800597 std::unique_ptr<VideoEncoder> encoder(
598 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
599 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100600 RunBaseTest(&test);
601}
602
danilchap9f5b6222017-03-02 06:22:21 -0800603// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
604TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800605 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
606 UlpfecObserver test(false, true, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100607 RunBaseTest(&test);
608}
609
Peter Boström12996152016-05-14 02:03:18 +0200610#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800611// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
612TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800613 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
614 UlpfecObserver test(false, true, true, true, "VP9", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800615 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000616}
Peter Boström12996152016-05-14 02:03:18 +0200617#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000618
brandtre78d2662017-01-16 05:57:16 -0800619TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800620 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800621 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800622 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
623 RunBaseTest(&test);
624}
625
brandtr39f97292016-11-16 22:57:50 -0800626// TODO(brandtr): Move these FlexFEC tests when we have created
627// FlexfecSendStream.
628class FlexfecObserver : public test::EndToEndTest {
629 public:
630 FlexfecObserver(bool header_extensions_enabled,
631 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800632 const std::string& codec,
633 VideoEncoder* encoder)
brandtr39f97292016-11-16 22:57:50 -0800634 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800635 encoder_(encoder),
brandtr39f97292016-11-16 22:57:50 -0800636 payload_name_(codec),
637 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800638 sent_media_(false),
639 sent_flexfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800640 header_extensions_enabled_(header_extensions_enabled) {}
brandtr39f97292016-11-16 22:57:50 -0800641
642 size_t GetNumFlexfecStreams() const override { return 1; }
643
644 private:
645 Action OnSendRtp(const uint8_t* packet, size_t length) override {
646 RTPHeader header;
647 EXPECT_TRUE(parser_->Parse(packet, length, &header));
648
brandtr39f97292016-11-16 22:57:50 -0800649 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
650 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
651 sent_flexfec_ = true;
652 } else {
653 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
654 header.payloadType);
655 EXPECT_EQ(VideoSendStreamTest::kVideoSendSsrcs[0], header.ssrc);
656 sent_media_ = true;
657 }
658
659 if (header_extensions_enabled_) {
660 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
661 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
662 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
663 }
664
brandtr0c5a1542016-11-23 04:42:26 -0800665 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800666 observation_complete_.Set();
667 }
668
669 return SEND_PACKET;
670 }
671
672 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
673 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
674 // Therefore we need some network delay.
675 const int kNetworkDelayMs = 100;
676 FakeNetworkPipe::Config config;
brandtrd654a9b2016-12-05 05:38:19 -0800677 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800678 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700679 return new test::PacketTransport(
680 sender_call, this, test::PacketTransport::kSender,
681 VideoSendStreamTest::payload_type_map_, config);
brandtr39f97292016-11-16 22:57:50 -0800682 }
683
684 void ModifyVideoConfigs(
685 VideoSendStream::Config* send_config,
686 std::vector<VideoReceiveStream::Config>* receive_configs,
687 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800688 if (use_nack_) {
689 send_config->rtp.nack.rtp_history_ms =
690 (*receive_configs)[0].rtp.nack.rtp_history_ms =
691 VideoSendStreamTest::kNackRtpHistoryMs;
692 }
brandtr696c9c62016-12-19 05:47:28 -0800693 send_config->encoder_settings.encoder = encoder_;
brandtr39f97292016-11-16 22:57:50 -0800694 send_config->encoder_settings.payload_name = payload_name_;
695 if (header_extensions_enabled_) {
696 send_config->rtp.extensions.push_back(RtpExtension(
697 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
698 send_config->rtp.extensions.push_back(RtpExtension(
699 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800700 } else {
701 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800702 }
703 }
704
705 void PerformTest() override {
706 EXPECT_TRUE(Wait())
707 << "Timed out waiting for FlexFEC and/or media packets.";
708 }
709
brandtr696c9c62016-12-19 05:47:28 -0800710 VideoEncoder* const encoder_;
711 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800712 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800713 bool sent_media_;
714 bool sent_flexfec_;
715 bool header_extensions_enabled_;
716};
717
brandtrd654a9b2016-12-05 05:38:19 -0800718TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800719 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
720 FlexfecObserver test(false, false, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800721 RunBaseTest(&test);
722}
723
724TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800725 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
726 FlexfecObserver test(false, true, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800727 RunBaseTest(&test);
728}
729
brandtr39f97292016-11-16 22:57:50 -0800730TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800731 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
732 FlexfecObserver test(true, false, "VP8", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800733 RunBaseTest(&test);
734}
735
brandtr39f97292016-11-16 22:57:50 -0800736#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800737TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800738 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
739 FlexfecObserver test(false, false, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800740 RunBaseTest(&test);
741}
742
brandtrd654a9b2016-12-05 05:38:19 -0800743TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800744 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
745 FlexfecObserver test(false, true, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800746 RunBaseTest(&test);
747}
748#endif // defined(RTC_DISABLE_VP9)
749
brandtrd654a9b2016-12-05 05:38:19 -0800750TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
brandtr696c9c62016-12-19 05:47:28 -0800751 std::unique_ptr<VideoEncoder> encoder(
752 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
753 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800754 RunBaseTest(&test);
755}
756
brandtrd654a9b2016-12-05 05:38:19 -0800757TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
brandtr696c9c62016-12-19 05:47:28 -0800758 std::unique_ptr<VideoEncoder> encoder(
759 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
760 FlexfecObserver test(false, true, "H264", encoder.get());
761 RunBaseTest(&test);
762}
763
brandtre78d2662017-01-16 05:57:16 -0800764TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800765 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800766 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800767 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800768 RunBaseTest(&test);
769}
770
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000771void VideoSendStreamTest::TestNackRetransmission(
772 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000773 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000774 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000775 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000776 explicit NackObserver(uint32_t retransmit_ssrc,
777 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000778 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000779 send_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000780 retransmit_ssrc_(retransmit_ssrc),
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000781 retransmit_payload_type_(retransmit_payload_type),
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000782 nacked_sequence_number_(-1) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000783 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000784
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000785 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000786 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000787 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000788 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000789
790 // Nack second packet after receiving the third one.
791 if (++send_count_ == 3) {
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000792 uint16_t nack_sequence_number = header.sequenceNumber - 1;
793 nacked_sequence_number_ = nack_sequence_number;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000794 NullReceiveStatistics null_stats;
Peter Boströmac547a62015-09-17 23:03:57 +0200795 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), &null_stats,
terelius429c3452016-01-21 05:42:04 -0800796 nullptr, nullptr, transport_adapter_.get());
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000797
pbosda903ea2015-10-02 02:36:56 -0700798 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100799 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000800
801 RTCPSender::FeedbackState feedback_state;
802
803 EXPECT_EQ(0,
804 rtcp_sender.SendRTCP(
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000805 feedback_state, kRtcpNack, 1, &nack_sequence_number));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000806 }
807
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000808 uint16_t sequence_number = header.sequenceNumber;
809
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000810 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100811 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
812 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000813 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000814 const uint8_t* rtx_header = packet + header.headerLength;
815 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
816 }
817
818 if (sequence_number == nacked_sequence_number_) {
819 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000820 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
Peter Boström5811a392015-12-10 13:02:50 +0100821 observation_complete_.Set();
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000822 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000823
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000824 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000825 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000826
stefanff483612015-12-21 03:14:00 -0800827 void ModifyVideoConfigs(
828 VideoSendStream::Config* send_config,
829 std::vector<VideoReceiveStream::Config>* receive_configs,
830 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700831 transport_adapter_.reset(
832 new internal::TransportAdapter(send_config->send_transport));
833 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000834 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000835 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100836 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000837 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
838 }
839
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000840 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100841 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000842 }
843
kwiberg27f982b2016-03-01 11:52:33 -0800844 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000845 int send_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000846 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000847 uint8_t retransmit_payload_type_;
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000848 int nacked_sequence_number_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000849 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000850
stefane74eef12016-01-08 06:47:13 -0800851 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000852}
853
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000854TEST_F(VideoSendStreamTest, RetransmitsNack) {
855 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100856 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000857}
858
859TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
860 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000861 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000862}
863
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000864void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
865 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000866 // Use a fake encoder to output a frame of every size in the range [90, 290],
867 // for each size making sure that the exact number of payload bytes received
868 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000869 static const size_t kMaxPacketSize = 128;
870 static const size_t start = 90;
871 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000872
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000873 // Observer that verifies that the expected number of packets and bytes
874 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000875 class FrameFragmentationTest : public test::SendTest,
876 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000877 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000878 FrameFragmentationTest(size_t max_packet_size,
879 size_t start_size,
880 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000881 bool test_generic_packetization,
882 bool use_fec)
883 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000884 encoder_(stop),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000885 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000886 stop_size_(stop_size),
887 test_generic_packetization_(test_generic_packetization),
888 use_fec_(use_fec),
889 packet_count_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000890 accumulated_size_(0),
891 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000892 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000893 current_size_rtp_(start_size),
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000894 current_size_frame_(static_cast<int32_t>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000895 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000896 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700897 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000898 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000899
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000900 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000901 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000902 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000903 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000904 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000905
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000906 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000907
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000908 if (use_fec_) {
909 uint8_t payload_type = packet[header.headerLength];
910 bool is_fec = header.payloadType == kRedPayloadType &&
911 payload_type == kUlpfecPayloadType;
912 if (is_fec) {
913 fec_packet_received_ = true;
914 return SEND_PACKET;
915 }
916 }
917
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000918 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000919
920 if (use_fec_)
921 TriggerLossReport(header);
922
923 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200924 size_t overhead = header.headerLength + header.paddingLength;
925 // Only remove payload header and RED header if the packet actually
926 // contains payload.
927 if (length > overhead) {
928 overhead += (1 /* Generic header */);
929 if (use_fec_)
930 overhead += 1; // RED for FEC header.
931 }
932 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000933 accumulated_payload_ += length - overhead;
934 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000935
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000936 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000937 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000938 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
939 // With FEC enabled, frame size is incremented asynchronously, so
940 // "old" frames one byte too small may arrive. Accept, but don't
941 // increase expected frame size.
942 accumulated_size_ = 0;
943 accumulated_payload_ = 0;
944 return SEND_PACKET;
945 }
946
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000947 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000948 if (test_generic_packetization_) {
949 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
950 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000951
952 // Last packet of frame; reset counters.
953 accumulated_size_ = 0;
954 accumulated_payload_ = 0;
955 if (current_size_rtp_ == stop_size_) {
956 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +0100957 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000958 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000959 // Increase next expected frame size. If testing with FEC, make sure
960 // a FEC packet has been received for this frame size before
961 // proceeding, to make sure that redundancy packets don't exceed
962 // size limit.
963 if (!use_fec_) {
964 ++current_size_rtp_;
965 } else if (fec_packet_received_) {
966 fec_packet_received_ = false;
967 ++current_size_rtp_;
968 ++current_size_frame_;
969 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000970 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000971 }
972
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000973 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000974 }
975
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000976 void TriggerLossReport(const RTPHeader& header) {
977 // Send lossy receive reports to trigger FEC enabling.
sprang4847ae62017-06-27 07:06:52 -0700978 const int kLossPercent = 5;
979 if (packet_count_++ % (100 / kLossPercent) != 0) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000980 FakeReceiveStatistics lossy_receive_stats(
sprang4847ae62017-06-27 07:06:52 -0700981 kVideoSendSsrcs[0], header.sequenceNumber,
982 (packet_count_ * (100 - kLossPercent)) / 100, // Cumulative lost.
983 static_cast<uint8_t>((255 * kLossPercent) / 100)); // Loss percent.
Peter Boströmac547a62015-09-17 23:03:57 +0200984 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -0800985 &lossy_receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -0700986 transport_adapter_.get());
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000987
pbosda903ea2015-10-02 02:36:56 -0700988 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100989 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000990
991 RTCPSender::FeedbackState feedback_state;
992
993 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
994 }
995 }
996
nisseef8b61e2016-04-29 06:09:15 -0700997 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000998 // Increase frame size for next encoded frame, in the context of the
999 // encoder thread.
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001000 if (!use_fec_ &&
1001 current_size_frame_.Value() < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001002 ++current_size_frame_;
1003 }
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001004 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_.Value()));
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001005 }
1006
Stefan Holmere5904162015-03-26 11:11:06 +01001007 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07001008 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01001009 const int kMinBitrateBps = 30000;
1010 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
1011 return config;
1012 }
1013
stefanff483612015-12-21 03:14:00 -08001014 void ModifyVideoConfigs(
1015 VideoSendStream::Config* send_config,
1016 std::vector<VideoReceiveStream::Config>* receive_configs,
1017 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001018 transport_adapter_.reset(
1019 new internal::TransportAdapter(send_config->send_transport));
1020 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001021 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -07001022 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
1023 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001024 }
1025
1026 if (!test_generic_packetization_)
1027 send_config->encoder_settings.payload_name = "VP8";
1028
1029 send_config->encoder_settings.encoder = &encoder_;
1030 send_config->rtp.max_packet_size = kMaxPacketSize;
1031 send_config->post_encode_callback = this;
1032
Erik Språng95261872015-04-10 11:58:49 +02001033 // Make sure there is at least one extension header, to make the RTP
1034 // header larger than the base length of 12 bytes.
1035 EXPECT_FALSE(send_config->rtp.extensions.empty());
sprang4847ae62017-06-27 07:06:52 -07001036
1037 // Setup screen content disables frame dropping which makes this easier.
1038 class VideoStreamFactory
1039 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1040 public:
1041 explicit VideoStreamFactory(size_t num_temporal_layers)
1042 : num_temporal_layers_(num_temporal_layers) {
1043 EXPECT_GT(num_temporal_layers, 0u);
1044 }
1045
1046 private:
1047 std::vector<VideoStream> CreateEncoderStreams(
1048 int width,
1049 int height,
1050 const VideoEncoderConfig& encoder_config) override {
1051 std::vector<VideoStream> streams =
1052 test::CreateVideoStreams(width, height, encoder_config);
1053 for (VideoStream& stream : streams) {
1054 stream.temporal_layer_thresholds_bps.resize(num_temporal_layers_ -
1055 1);
1056 }
1057 return streams;
1058 }
1059 const size_t num_temporal_layers_;
1060 };
1061
1062 encoder_config->video_stream_factory =
1063 new rtc::RefCountedObject<VideoStreamFactory>(2);
1064 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001065 }
1066
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001067 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001068 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001069 }
1070
kwiberg27f982b2016-03-01 11:52:33 -08001071 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001072 test::ConfigurableFrameSizeEncoder encoder_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001073
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001074 const size_t max_packet_size_;
1075 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001076 const bool test_generic_packetization_;
1077 const bool use_fec_;
1078
1079 uint32_t packet_count_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001080 size_t accumulated_size_;
1081 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001082 bool fec_packet_received_;
1083
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001084 size_t current_size_rtp_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001085 Atomic32 current_size_frame_;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001086 };
1087
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001088 // Don't auto increment if FEC is used; continue sending frame size until
1089 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001090 FrameFragmentationTest test(
1091 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001092
stefane74eef12016-01-08 06:47:13 -08001093 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001094}
1095
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001096// TODO(sprang): Is there any way of speeding up these tests?
1097TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
1098 TestPacketFragmentationSize(kGeneric, false);
1099}
1100
1101TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
1102 TestPacketFragmentationSize(kGeneric, true);
1103}
1104
1105TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
1106 TestPacketFragmentationSize(kVP8, false);
1107}
1108
1109TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
1110 TestPacketFragmentationSize(kVP8, true);
1111}
1112
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001113// The test will go through a number of phases.
1114// 1. Start sending packets.
1115// 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 +00001116// suspend the stream.
1117// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001118// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001119// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001120// When the stream is detected again, and the stats show that the stream
1121// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001122TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1123 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001124
nissed30a1112016-04-18 05:15:22 -07001125 class RembObserver : public test::SendTest,
1126 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001127 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001128 RembObserver()
1129 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001130 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001131 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001132 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001133 rtp_count_(0),
1134 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001135 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001136 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001137 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001138
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001139 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001140 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001141 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001142 ++rtp_count_;
1143 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001144 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001145 last_sequence_number_ = header.sequenceNumber;
1146
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001147 if (test_state_ == kBeforeSuspend) {
1148 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001149 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001150 test_state_ = kDuringSuspend;
1151 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001152 if (header.paddingLength == 0) {
1153 // Received non-padding packet during suspension period. Reset the
1154 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001155 suspended_frame_count_ = 0;
1156 }
stefanf116bd02015-10-27 08:29:42 -07001157 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001158 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001159 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001160 // Non-padding packet observed. Test is almost complete. Will just
1161 // have to wait for the stats to change.
1162 test_state_ = kWaitingForStats;
1163 }
stefanf116bd02015-10-27 08:29:42 -07001164 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001165 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001166 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001167 if (stats.suspended == false) {
1168 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001169 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001170 }
stefanf116bd02015-10-27 08:29:42 -07001171 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001172 }
1173
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001174 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001175 }
1176
perkj26091b12016-09-01 01:17:40 -07001177 // This method implements the rtc::VideoSinkInterface. This is called when
1178 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001179 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001180 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001181 if (test_state_ == kDuringSuspend &&
1182 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001183 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001184 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001185 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001186 test_state_ = kWaitingForPacket;
1187 }
1188 }
1189
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001190 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001191 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001192 low_remb_bps_ = value;
1193 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001194
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001195 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001196 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001197 high_remb_bps_ = value;
1198 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001199
stefanff483612015-12-21 03:14:00 -08001200 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001201 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001202 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001203 stream_ = send_stream;
1204 }
1205
stefanff483612015-12-21 03:14:00 -08001206 void ModifyVideoConfigs(
1207 VideoSendStream::Config* send_config,
1208 std::vector<VideoReceiveStream::Config>* receive_configs,
1209 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001210 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001211 transport_adapter_.reset(
1212 new internal::TransportAdapter(send_config->send_transport));
1213 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001214 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001215 send_config->pre_encode_callback = this;
1216 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001217 int min_bitrate_bps =
1218 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001219 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001220 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001221 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001222 min_bitrate_bps + threshold_window + 5000);
1223 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1224 }
1225
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001226 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001227 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001228 }
1229
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001230 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001231 kBeforeSuspend,
1232 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001233 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001234 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001235 };
1236
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001237 virtual void SendRtcpFeedback(int remb_value)
1238 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001239 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1240 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001241 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -07001242 transport_adapter_.get());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001243
pbosda903ea2015-10-02 02:36:56 -07001244 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001245 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001246 if (remb_value > 0) {
1247 rtcp_sender.SetREMBStatus(true);
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001248 rtcp_sender.SetREMBData(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001249 }
1250 RTCPSender::FeedbackState feedback_state;
1251 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1252 }
1253
kwiberg27f982b2016-03-01 11:52:33 -08001254 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001255 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001256 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001257
Peter Boströmf2f82832015-05-01 13:00:41 +02001258 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001259 TestState test_state_ GUARDED_BY(crit_);
1260 int rtp_count_ GUARDED_BY(crit_);
1261 int last_sequence_number_ GUARDED_BY(crit_);
1262 int suspended_frame_count_ GUARDED_BY(crit_);
1263 int low_remb_bps_ GUARDED_BY(crit_);
1264 int high_remb_bps_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001265 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001266
stefane74eef12016-01-08 06:47:13 -08001267 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001268}
1269
perkj71ee44c2016-06-15 00:47:53 -07001270// This test that padding stops being send after a while if the Camera stops
1271// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001272TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001273 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001274 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001275 NoPaddingWhenVideoIsMuted()
1276 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001277 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001278 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001279 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +00001280 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001281
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001282 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001283 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001284 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001285 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001286
1287 RTPHeader header;
1288 parser_->Parse(packet, length, &header);
1289 const bool only_padding =
1290 header.headerLength + header.paddingLength == length;
1291
1292 if (test_state_ == kBeforeStopCapture) {
1293 capturer_->Stop();
1294 test_state_ = kWaitingForPadding;
1295 } else if (test_state_ == kWaitingForPadding && only_padding) {
1296 test_state_ = kWaitingForNoPackets;
1297 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1298 only_padding) {
1299 observation_complete_.Set();
1300 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001301 return SEND_PACKET;
1302 }
1303
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001304 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001305 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001306 const int kNoPacketsThresholdMs = 2000;
1307 if (test_state_ == kWaitingForNoPackets &&
1308 (last_packet_time_ms_ > 0 &&
1309 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1310 kNoPacketsThresholdMs)) {
1311 capturer_->Start();
1312 test_state_ = kWaitingForPaddingAfterCameraRestart;
1313 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001314 return SEND_PACKET;
1315 }
1316
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001317 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001318
nisseef8b61e2016-04-29 06:09:15 -07001319 void OnFrameGeneratorCapturerCreated(
1320 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001321 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001322 capturer_ = frame_generator_capturer;
1323 }
1324
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001325 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001326 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001327 << "Timed out while waiting for RTP packets to stop being sent.";
1328 }
1329
perkj71ee44c2016-06-15 00:47:53 -07001330 enum TestState {
1331 kBeforeStopCapture,
1332 kWaitingForPadding,
1333 kWaitingForNoPackets,
1334 kWaitingForPaddingAfterCameraRestart
1335 };
1336
1337 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001338 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001339 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001340 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001341 int64_t last_packet_time_ms_ GUARDED_BY(crit_);
1342 test::FrameGeneratorCapturer* capturer_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001343 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001344
stefane74eef12016-01-08 06:47:13 -08001345 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001346}
1347
isheriffcc5903e2016-10-04 08:29:38 -07001348TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1349 const int kCapacityKbps = 10000; // 10 Mbps
1350 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1351 public:
1352 PaddingIsPrimarilyRetransmissions()
1353 : EndToEndTest(kDefaultTimeoutMs),
1354 clock_(Clock::GetRealTimeClock()),
1355 padding_length_(0),
1356 total_length_(0),
1357 call_(nullptr) {}
1358
1359 private:
1360 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1361 call_ = sender_call;
1362 }
1363
1364 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1365 rtc::CritScope lock(&crit_);
1366
1367 RTPHeader header;
1368 parser_->Parse(packet, length, &header);
1369 padding_length_ += header.paddingLength;
1370 total_length_ += length;
1371 return SEND_PACKET;
1372 }
1373
1374 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
1375 const int kNetworkDelayMs = 50;
1376 FakeNetworkPipe::Config config;
1377 config.loss_percent = 10;
1378 config.link_capacity_kbps = kCapacityKbps;
1379 config.queue_delay_ms = kNetworkDelayMs;
1380 return new test::PacketTransport(sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -07001381 test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -07001382 payload_type_map_, config);
isheriffcc5903e2016-10-04 08:29:38 -07001383 }
1384
1385 void ModifyVideoConfigs(
1386 VideoSendStream::Config* send_config,
1387 std::vector<VideoReceiveStream::Config>* receive_configs,
1388 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001389 // Turn on RTX.
1390 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1391 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001392 }
1393
1394 void PerformTest() override {
1395 // TODO(isheriff): Some platforms do not ramp up as expected to full
1396 // capacity due to packet scheduling delays. Fix that before getting
1397 // rid of this.
1398 SleepMs(5000);
1399 {
1400 rtc::CritScope lock(&crit_);
1401 // Expect padding to be a small percentage of total bytes sent.
1402 EXPECT_LT(padding_length_, .1 * total_length_);
1403 }
1404 }
1405
1406 rtc::CriticalSection crit_;
1407 Clock* const clock_;
1408 size_t padding_length_ GUARDED_BY(crit_);
1409 size_t total_length_ GUARDED_BY(crit_);
1410 Call* call_;
1411 } test;
1412
1413 RunBaseTest(&test);
1414}
1415
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001416// This test first observes "high" bitrate use at which point it sends a REMB to
1417// indicate that it should be lowered significantly. The test then observes that
1418// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1419// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001420//
1421// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1422// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001423TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1424 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001425 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001426 static const int kRembBitrateBps = 80000;
1427 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001428 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001429 public:
1430 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001431 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001432 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1433 stream_(nullptr),
1434 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001435
1436 private:
nisseef8b61e2016-04-29 06:09:15 -07001437 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001438 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001439 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001440
1441 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001442 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001443 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001444 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001445 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001446 if (!stats.substreams.empty()) {
1447 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001448 int total_bitrate_bps =
1449 stats.substreams.begin()->second.total_bitrate_bps;
1450 test::PrintResult("bitrate_stats_",
1451 "min_transmit_bitrate_low_remb",
1452 "bitrate_bps",
1453 static_cast<size_t>(total_bitrate_bps),
1454 "bps",
1455 false);
1456 if (total_bitrate_bps > kHighBitrateBps) {
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001457 rtp_rtcp_->SetREMBData(kRembBitrateBps,
1458 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001459 rtp_rtcp_->Process();
1460 bitrate_capped_ = true;
1461 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001462 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001463 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001464 }
1465 }
stefanf116bd02015-10-27 08:29:42 -07001466 // Packets don't have to be delivered since the test is the receiver.
1467 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001468 }
1469
stefanff483612015-12-21 03:14:00 -08001470 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001471 VideoSendStream* send_stream,
1472 const std::vector<VideoReceiveStream*>& receive_streams) override {
1473 stream_ = send_stream;
1474 RtpRtcp::Configuration config;
1475 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001476 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001477 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
1478 rtp_rtcp_->SetREMBStatus(true);
1479 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001480 }
1481
stefanff483612015-12-21 03:14:00 -08001482 void ModifyVideoConfigs(
1483 VideoSendStream::Config* send_config,
1484 std::vector<VideoReceiveStream::Config>* receive_configs,
1485 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001486 feedback_transport_.reset(
1487 new internal::TransportAdapter(send_config->send_transport));
1488 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001489 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001490 }
1491
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001492 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001493 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001494 << "Timeout while waiting for low bitrate stats after REMB.";
1495 }
1496
kwiberg27f982b2016-03-01 11:52:33 -08001497 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1498 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001499 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001500 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001501 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001502 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001503
stefane74eef12016-01-08 06:47:13 -08001504 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001505}
1506
Stefan Holmer280de9e2016-09-30 10:06:51 +02001507TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1508 static const int kStartBitrateBps = 300000;
1509 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001510 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001511 class ChangingNetworkRouteTest : public test::EndToEndTest {
1512 public:
Stefan Holmerbe402962016-07-08 16:16:41 +02001513 ChangingNetworkRouteTest()
Stefan Holmer280de9e2016-09-30 10:06:51 +02001514 : EndToEndTest(test::CallTest::kDefaultTimeoutMs), call_(nullptr) {
1515 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1516 kRtpExtensionTransportSequenceNumber, kExtensionId));
1517 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001518
1519 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1520 call_ = sender_call;
1521 }
1522
Stefan Holmer280de9e2016-09-30 10:06:51 +02001523 void ModifyVideoConfigs(
1524 VideoSendStream::Config* send_config,
1525 std::vector<VideoReceiveStream::Config>* receive_configs,
1526 VideoEncoderConfig* encoder_config) override {
1527 send_config->rtp.extensions.clear();
1528 send_config->rtp.extensions.push_back(RtpExtension(
1529 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1530 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1531 (*receive_configs)[0].rtp.transport_cc = true;
1532 }
1533
1534 void ModifyAudioConfigs(
1535 AudioSendStream::Config* send_config,
1536 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1537 send_config->rtp.extensions.clear();
1538 send_config->rtp.extensions.push_back(RtpExtension(
1539 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1540 (*receive_configs)[0].rtp.extensions.clear();
1541 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1542 (*receive_configs)[0].rtp.transport_cc = true;
1543 }
1544
Stefan Holmerbe402962016-07-08 16:16:41 +02001545 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1546 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1547 observation_complete_.Set();
1548 }
1549
1550 return SEND_PACKET;
1551 }
1552
1553 void PerformTest() override {
1554 rtc::NetworkRoute new_route(true, 10, 20, -1);
1555 call_->OnNetworkRouteChanged("transport", new_route);
1556 Call::Config::BitrateConfig bitrate_config;
1557 bitrate_config.start_bitrate_bps = kStartBitrateBps;
1558 call_->SetBitrateConfig(bitrate_config);
1559 EXPECT_TRUE(Wait())
1560 << "Timed out while waiting for start bitrate to be exceeded.";
1561
1562 bitrate_config.start_bitrate_bps = -1;
1563 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
1564 call_->SetBitrateConfig(bitrate_config);
1565 // TODO(holmer): We should set the last sent packet id here and verify
1566 // that we correctly ignore any packet loss reported prior to that id.
1567 ++new_route.local_network_id;
1568 call_->OnNetworkRouteChanged("transport", new_route);
stefan01bbc3c2016-10-25 04:19:48 -07001569 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
Stefan Holmerbe402962016-07-08 16:16:41 +02001570 }
1571
1572 private:
1573 Call* call_;
1574 } test;
1575
1576 RunBaseTest(&test);
1577}
1578
michaelt79e05882016-11-08 02:50:09 -08001579TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
1580 class ChangingTransportOverheadTest : public test::EndToEndTest {
1581 public:
1582 ChangingTransportOverheadTest()
1583 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1584 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001585 packets_sent_(0),
1586 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001587
1588 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1589 call_ = sender_call;
1590 }
1591
1592 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001593 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001594 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001595 if (++packets_sent_ < 100)
1596 return SEND_PACKET;
1597 observation_complete_.Set();
1598 return SEND_PACKET;
1599 }
1600
michaelta3328772016-11-29 09:25:03 -08001601 void ModifyVideoConfigs(
1602 VideoSendStream::Config* send_config,
1603 std::vector<VideoReceiveStream::Config>* receive_configs,
1604 VideoEncoderConfig* encoder_config) override {
1605 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1606 }
1607
michaelt79e05882016-11-08 02:50:09 -08001608 void PerformTest() override {
michaelta3328772016-11-29 09:25:03 -08001609 transport_overhead_ = 100;
michaelt79e05882016-11-08 02:50:09 -08001610 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1611 transport_overhead_);
1612 EXPECT_TRUE(Wait());
sprang21253fc2017-02-27 03:35:47 -08001613 {
1614 rtc::CritScope cs(&lock_);
1615 packets_sent_ = 0;
1616 }
michaelta3328772016-11-29 09:25:03 -08001617 transport_overhead_ = 500;
michaelt79e05882016-11-08 02:50:09 -08001618 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1619 transport_overhead_);
1620 EXPECT_TRUE(Wait());
1621 }
1622
1623 private:
1624 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001625 rtc::CriticalSection lock_;
1626 int packets_sent_ GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001627 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001628 const size_t kMaxRtpPacketSize = 1000;
michaelt79e05882016-11-08 02:50:09 -08001629 } test;
1630
1631 RunBaseTest(&test);
1632}
1633
sprangf24a0642017-02-28 13:23:26 -08001634// Test class takes takes as argument a switch selecting if type switch should
1635// occur and a function pointer to reset the send stream. This is necessary
1636// since you cannot change the content type of a VideoSendStream, you need to
1637// recreate it. Stopping and recreating the stream can only be done on the main
1638// thread and in the context of VideoSendStreamTest (not BaseTest).
1639template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001640class MaxPaddingSetTest : public test::SendTest {
1641 public:
1642 static const uint32_t kMinTransmitBitrateBps = 400000;
1643 static const uint32_t kActualEncodeBitrateBps = 40000;
1644 static const uint32_t kMinPacketsToSend = 50;
1645
sprangf24a0642017-02-28 13:23:26 -08001646 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001647 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001648 content_switch_event_(false, false),
sprang9c0b5512016-07-06 00:54:28 -07001649 call_(nullptr),
1650 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001651 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001652 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001653 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001654 stream_resetter_(stream_reset_fun) {
1655 RTC_DCHECK(stream_resetter_);
1656 }
sprang9c0b5512016-07-06 00:54:28 -07001657
1658 void OnVideoStreamsCreated(
1659 VideoSendStream* send_stream,
1660 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001661 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001662 send_stream_ = send_stream;
1663 }
1664
1665 void ModifyVideoConfigs(
1666 VideoSendStream::Config* send_config,
1667 std::vector<VideoReceiveStream::Config>* receive_configs,
1668 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001669 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001670 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001671 encoder_config->min_transmit_bitrate_bps = 0;
1672 encoder_config->content_type =
1673 VideoEncoderConfig::ContentType::kRealtimeVideo;
1674 } else {
1675 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1676 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1677 }
sprangf24a0642017-02-28 13:23:26 -08001678 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001679 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001680 }
1681
1682 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1683 call_ = sender_call;
1684 }
1685
1686 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1687 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001688 if (running_without_padding_)
1689 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1690
1691 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1692 // we have reliable data.
1693 if (++packets_sent_ < kMinPacketsToSend)
1694 return SEND_PACKET;
1695
1696 if (running_without_padding_) {
1697 // We've sent kMinPacketsToSend packets with default configuration, switch
1698 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001699 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001700 packets_sent_ = 0;
1701 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1702 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001703 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001704 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001705 return SEND_PACKET;
1706 }
1707
1708 // Make sure the pacer has been configured with a min transmit bitrate.
1709 if (call_->GetStats().max_padding_bitrate_bps > 0)
1710 observation_complete_.Set();
1711
1712 return SEND_PACKET;
1713 }
1714
1715 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001716 if (RunningWithoutPadding()) {
1717 ASSERT_TRUE(
1718 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001719 (*stream_resetter_)(send_stream_config_, encoder_config_);
1720 }
1721
sprang9c0b5512016-07-06 00:54:28 -07001722 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1723 }
1724
1725 private:
sprangf24a0642017-02-28 13:23:26 -08001726 bool RunningWithoutPadding() const {
1727 rtc::CritScope lock(&crit_);
1728 return running_without_padding_;
1729 }
1730
sprang9c0b5512016-07-06 00:54:28 -07001731 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001732 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001733 Call* call_;
sprangf24a0642017-02-28 13:23:26 -08001734 VideoSendStream* send_stream_ GUARDED_BY(crit_);
1735 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001736 VideoEncoderConfig encoder_config_;
1737 uint32_t packets_sent_ GUARDED_BY(crit_);
1738 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001739 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001740};
1741
1742TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001743 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1744 const VideoEncoderConfig& encoder_config) {};
1745 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001746 RunBaseTest(&test);
1747}
1748
1749TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001750 // Function for removing and recreating the send stream with a new config.
1751 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1752 const VideoEncoderConfig& encoder_config) {
1753 Stop();
1754 sender_call_->DestroyVideoSendStream(video_send_stream_);
1755 video_send_config_ = send_stream_config.Copy();
1756 video_encoder_config_ = encoder_config.Copy();
1757 video_send_stream_ = sender_call_->CreateVideoSendStream(
1758 video_send_config_.Copy(), video_encoder_config_.Copy());
1759 video_send_stream_->SetSource(
1760 frame_generator_capturer_.get(),
1761 VideoSendStream::DegradationPreference::kMaintainResolution);
1762 Start();
1763 };
1764 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001765 RunBaseTest(&test);
1766}
1767
perkjfa10b552016-10-02 23:45:26 -07001768// This test verifies that new frame sizes reconfigures encoders even though not
1769// (yet) sending. The purpose of this is to permit encoding as quickly as
1770// possible once we start sending. Likely the frames being input are from the
1771// same source that will be sent later, which just means that we're ready
1772// earlier.
1773TEST_F(VideoSendStreamTest,
1774 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1775 class EncoderObserver : public test::FakeEncoder {
1776 public:
1777 EncoderObserver()
1778 : FakeEncoder(Clock::GetRealTimeClock()),
1779 init_encode_called_(false, false),
1780 number_of_initializations_(0),
1781 last_initialized_frame_width_(0),
1782 last_initialized_frame_height_(0) {}
1783
1784 void WaitForResolution(int width, int height) {
1785 {
1786 rtc::CritScope lock(&crit_);
1787 if (last_initialized_frame_width_ == width &&
1788 last_initialized_frame_height_ == height) {
1789 return;
1790 }
1791 }
Erik Språng08127a92016-11-16 16:41:30 +01001792 EXPECT_TRUE(
1793 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001794 {
1795 rtc::CritScope lock(&crit_);
1796 EXPECT_EQ(width, last_initialized_frame_width_);
1797 EXPECT_EQ(height, last_initialized_frame_height_);
1798 }
1799 }
1800
1801 private:
1802 int32_t InitEncode(const VideoCodec* config,
1803 int32_t number_of_cores,
1804 size_t max_payload_size) override {
1805 rtc::CritScope lock(&crit_);
1806 last_initialized_frame_width_ = config->width;
1807 last_initialized_frame_height_ = config->height;
1808 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001809 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001810 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1811 }
1812
1813 int32_t Encode(const VideoFrame& input_image,
1814 const CodecSpecificInfo* codec_specific_info,
1815 const std::vector<FrameType>* frame_types) override {
1816 ADD_FAILURE()
1817 << "Unexpected Encode call since the send stream is not started";
1818 return 0;
1819 }
1820
1821 rtc::CriticalSection crit_;
1822 rtc::Event init_encode_called_;
1823 size_t number_of_initializations_ GUARDED_BY(&crit_);
1824 int last_initialized_frame_width_ GUARDED_BY(&crit_);
1825 int last_initialized_frame_height_ GUARDED_BY(&crit_);
1826 };
1827
philipel4fb651d2017-04-10 03:54:05 -07001828 CreateSenderCall(Call::Config(event_log_.get()));
perkjfa10b552016-10-02 23:45:26 -07001829 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001830 CreateSendConfig(1, 0, 0, &transport);
perkjfa10b552016-10-02 23:45:26 -07001831 EncoderObserver encoder;
1832 video_send_config_.encoder_settings.encoder = &encoder;
1833 CreateVideoStreams();
1834 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1835 kDefaultHeight);
1836 frame_generator_capturer_->Start();
1837
1838 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
1839 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1840 kDefaultHeight * 2);
1841 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
1842 DestroyStreams();
1843}
1844
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001845TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1846 class StartBitrateObserver : public test::FakeEncoder {
1847 public:
1848 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001849 : FakeEncoder(Clock::GetRealTimeClock()),
1850 start_bitrate_changed_(false, false),
1851 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001852 int32_t InitEncode(const VideoCodec* config,
1853 int32_t number_of_cores,
1854 size_t max_payload_size) override {
1855 rtc::CritScope lock(&crit_);
1856 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001857 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001858 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1859 }
1860
1861 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1862 rtc::CritScope lock(&crit_);
1863 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001864 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001865 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1866 }
1867
1868 int GetStartBitrateKbps() const {
1869 rtc::CritScope lock(&crit_);
1870 return start_bitrate_kbps_;
1871 }
1872
pbos14fe7082016-04-20 06:35:56 -07001873 bool WaitForStartBitrate() {
1874 return start_bitrate_changed_.Wait(
1875 VideoSendStreamTest::kDefaultTimeoutMs);
1876 }
1877
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001878 private:
pbos5ad935c2016-01-25 03:52:44 -08001879 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001880 rtc::Event start_bitrate_changed_;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001881 int start_bitrate_kbps_ GUARDED_BY(crit_);
1882 };
1883
philipel4fb651d2017-04-10 03:54:05 -07001884 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001885
solenberg4fbae2b2015-08-28 04:07:10 -07001886 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001887 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001888
1889 Call::Config::BitrateConfig bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07001890 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001891 sender_call_->SetBitrateConfig(bitrate_config);
1892
1893 StartBitrateObserver encoder;
stefanff483612015-12-21 03:14:00 -08001894 video_send_config_.encoder_settings.encoder = &encoder;
perkjfa10b552016-10-02 23:45:26 -07001895 // Since this test does not use a capturer, set |internal_source| = true.
1896 // Encoder configuration is otherwise updated on the next video frame.
1897 video_send_config_.encoder_settings.internal_source = true;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001898
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001899 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001900
pbos14fe7082016-04-20 06:35:56 -07001901 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07001902 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001903 encoder.GetStartBitrateKbps());
1904
perkjfa10b552016-10-02 23:45:26 -07001905 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07001906 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001907
1908 // New bitrate should be reconfigured above the previous max. As there's no
1909 // network connection this shouldn't be flaky, as no bitrate should've been
1910 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07001911 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001912 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
1913 encoder.GetStartBitrateKbps());
1914
1915 DestroyStreams();
1916}
1917
perkj57c21f92016-06-17 07:27:16 -07001918// This test that if the encoder use an internal source, VideoEncoder::SetRates
1919// will be called with zero bitrate during initialization and that
1920// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
1921// with zero bitrate.
1922TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
1923 class StartStopBitrateObserver : public test::FakeEncoder {
1924 public:
1925 StartStopBitrateObserver()
1926 : FakeEncoder(Clock::GetRealTimeClock()),
1927 encoder_init_(false, false),
Erik Språng08127a92016-11-16 16:41:30 +01001928 bitrate_changed_(false, false) {}
perkj57c21f92016-06-17 07:27:16 -07001929 int32_t InitEncode(const VideoCodec* config,
1930 int32_t number_of_cores,
1931 size_t max_payload_size) override {
1932 rtc::CritScope lock(&crit_);
perkj57c21f92016-06-17 07:27:16 -07001933 encoder_init_.Set();
1934 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1935 }
1936
Erik Språng08127a92016-11-16 16:41:30 +01001937 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
1938 uint32_t framerate) override {
perkj57c21f92016-06-17 07:27:16 -07001939 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01001940 bitrate_kbps_ = rtc::Optional<int>(bitrate.get_sum_kbps());
perkj57c21f92016-06-17 07:27:16 -07001941 bitrate_changed_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01001942 return FakeEncoder::SetRateAllocation(bitrate, framerate);
perkj57c21f92016-06-17 07:27:16 -07001943 }
1944
1945 bool WaitForEncoderInit() {
1946 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1947 }
Erik Språng08127a92016-11-16 16:41:30 +01001948
1949 bool WaitBitrateChanged(bool non_zero) {
1950 do {
1951 rtc::Optional<int> bitrate_kbps;
1952 {
1953 rtc::CritScope lock(&crit_);
1954 bitrate_kbps = bitrate_kbps_;
1955 }
1956 if (!bitrate_kbps)
1957 continue;
1958
1959 if ((non_zero && *bitrate_kbps > 0) ||
1960 (!non_zero && *bitrate_kbps == 0)) {
1961 return true;
1962 }
1963 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
1964 return false;
perkj57c21f92016-06-17 07:27:16 -07001965 }
1966
1967 private:
1968 rtc::CriticalSection crit_;
1969 rtc::Event encoder_init_;
1970 rtc::Event bitrate_changed_;
Erik Språng08127a92016-11-16 16:41:30 +01001971 rtc::Optional<int> bitrate_kbps_ GUARDED_BY(crit_);
perkj57c21f92016-06-17 07:27:16 -07001972 };
1973
philipel4fb651d2017-04-10 03:54:05 -07001974 CreateSenderCall(Call::Config(event_log_.get()));
perkj57c21f92016-06-17 07:27:16 -07001975
1976 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001977 CreateSendConfig(1, 0, 0, &transport);
perkj57c21f92016-06-17 07:27:16 -07001978
Sergey Ulanove2b15012016-11-22 16:08:30 -08001979 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
1980
perkj57c21f92016-06-17 07:27:16 -07001981 StartStopBitrateObserver encoder;
1982 video_send_config_.encoder_settings.encoder = &encoder;
1983 video_send_config_.encoder_settings.internal_source = true;
1984
1985 CreateVideoStreams();
1986
1987 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01001988
perkj57c21f92016-06-17 07:27:16 -07001989 video_send_stream_->Start();
Erik Språng08127a92016-11-16 16:41:30 +01001990 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
1991
perkj57c21f92016-06-17 07:27:16 -07001992 video_send_stream_->Stop();
Erik Språng08127a92016-11-16 16:41:30 +01001993 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
1994
perkj57c21f92016-06-17 07:27:16 -07001995 video_send_stream_->Start();
Erik Språng08127a92016-11-16 16:41:30 +01001996 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07001997
1998 DestroyStreams();
1999}
2000
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002001TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07002002 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002003 public:
Peter Boström5811a392015-12-10 13:02:50 +01002004 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002005
nissed30a1112016-04-18 05:15:22 -07002006 void OnFrame(const VideoFrame& video_frame) override {
2007 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01002008 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002009 }
2010
2011 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01002012 const int kWaitFrameTimeoutMs = 3000;
2013 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002014 << "Timeout while waiting for output frames.";
2015 }
2016
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002017 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002018 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002019 }
2020
2021 private:
2022 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002023 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002024
2025 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01002026 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002027 };
2028
2029 // Initialize send stream.
philipel4fb651d2017-04-10 03:54:05 -07002030 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002031
solenberg4fbae2b2015-08-28 04:07:10 -07002032 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08002033 CreateSendConfig(1, 0, 0, &transport);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002034 FrameObserver observer;
stefanff483612015-12-21 03:14:00 -08002035 video_send_config_.pre_encode_callback = &observer;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002036 CreateVideoStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002037
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002038 // Prepare five input frames. Send ordinary VideoFrame and texture frames
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002039 // alternatively.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002040 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07002041 int width = 168;
2042 int height = 132;
2043
Magnus Jedvert90e31902017-06-07 11:32:50 +02002044 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2045 width, height, 1, 1, kVideoRotation_0));
2046 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2047 width, height, 2, 2, kVideoRotation_0));
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002048 input_frames.push_back(CreateVideoFrame(width, height, 3));
2049 input_frames.push_back(CreateVideoFrame(width, height, 4));
Magnus Jedvert90e31902017-06-07 11:32:50 +02002050 input_frames.push_back(test::FakeNativeBuffer::CreateFrame(
2051 width, height, 5, 5, kVideoRotation_0));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002052
stefanff483612015-12-21 03:14:00 -08002053 video_send_stream_->Start();
perkja49cbd32016-09-16 07:53:41 -07002054 test::FrameForwarder forwarder;
perkj803d97f2016-11-01 11:45:46 -07002055 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07002056 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002057 for (size_t i = 0; i < input_frames.size(); i++) {
perkja49cbd32016-09-16 07:53:41 -07002058 forwarder.IncomingCapturedFrame(input_frames[i]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002059 // Wait until the output frame is received before sending the next input
2060 // frame. Or the previous input frame may be replaced without delivering.
2061 observer.WaitOutputFrame();
2062 }
stefanff483612015-12-21 03:14:00 -08002063 video_send_stream_->Stop();
perkj803d97f2016-11-01 11:45:46 -07002064 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07002065 nullptr, VideoSendStream::DegradationPreference::kMaintainFramerate);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002066
2067 // Test if the input and output frames are the same. render_time_ms and
2068 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002069 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002070
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002071 DestroyStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002072}
2073
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002074void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
2075 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002076 EXPECT_EQ(frames1.size(), frames2.size());
2077 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07002078 // Compare frame buffers, since we don't care about differing timestamps.
2079 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
2080 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002081}
2082
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002083VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002084 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002085 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002086 memset(buffer.get(), data, kSizeY);
Magnus Jedvert90e31902017-06-07 11:32:50 +02002087 VideoFrame frame(I420Buffer::Create(width, height), kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002088 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002089 // Use data as a ms timestamp.
2090 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002091 return frame;
2092}
2093
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002094TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
2095 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2096 public:
2097 EncoderStateObserver()
2098 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002099 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002100 initialized_(false),
2101 callback_registered_(false),
2102 num_releases_(0),
2103 released_(false) {}
2104
2105 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002106 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002107 return released_;
2108 }
2109
2110 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002111 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002112 return initialized_ && callback_registered_;
2113 }
2114
2115 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002116 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002117 return num_releases_;
2118 }
2119
2120 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002121 int32_t InitEncode(const VideoCodec* codecSettings,
2122 int32_t numberOfCores,
2123 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002124 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002125 EXPECT_FALSE(initialized_);
2126 initialized_ = true;
2127 released_ = false;
2128 return 0;
2129 }
2130
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002131 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002132 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002133 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002134 EXPECT_TRUE(IsReadyForEncode());
2135
Peter Boström5811a392015-12-10 13:02:50 +01002136 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002137 return 0;
2138 }
2139
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002140 int32_t RegisterEncodeCompleteCallback(
2141 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002142 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002143 EXPECT_TRUE(initialized_);
2144 callback_registered_ = true;
2145 return 0;
2146 }
2147
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002148 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002149 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002150 EXPECT_TRUE(IsReadyForEncode());
2151 EXPECT_FALSE(released_);
2152 initialized_ = false;
2153 callback_registered_ = false;
2154 released_ = true;
2155 ++num_releases_;
2156 return 0;
2157 }
2158
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002159 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002160 EXPECT_TRUE(IsReadyForEncode());
2161 return 0;
2162 }
2163
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002164 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002165 EXPECT_TRUE(IsReadyForEncode());
2166 return 0;
2167 }
2168
stefanff483612015-12-21 03:14:00 -08002169 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002170 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002171 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002172 stream_ = send_stream;
2173 }
2174
stefanff483612015-12-21 03:14:00 -08002175 void ModifyVideoConfigs(
2176 VideoSendStream::Config* send_config,
2177 std::vector<VideoReceiveStream::Config>* receive_configs,
2178 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002179 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07002180 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002181 }
2182
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002183 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002184 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
Per21d45d22016-10-30 21:37:57 +01002185 EXPECT_EQ(0u, num_releases());
perkj26091b12016-09-01 01:17:40 -07002186 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
Per21d45d22016-10-30 21:37:57 +01002187 EXPECT_EQ(0u, num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002188 stream_->Stop();
2189 // Encoder should not be released before destroying the VideoSendStream.
2190 EXPECT_FALSE(IsReleased());
2191 EXPECT_TRUE(IsReadyForEncode());
2192 stream_->Start();
2193 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002194 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002195 }
2196
Peter Boströmf2f82832015-05-01 13:00:41 +02002197 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002198 VideoSendStream* stream_;
2199 bool initialized_ GUARDED_BY(crit_);
2200 bool callback_registered_ GUARDED_BY(crit_);
2201 size_t num_releases_ GUARDED_BY(crit_);
2202 bool released_ GUARDED_BY(crit_);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002203 VideoEncoderConfig encoder_config_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002204 } test_encoder;
2205
stefane74eef12016-01-08 06:47:13 -08002206 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002207
2208 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002209 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002210}
2211
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002212TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2213 class VideoCodecConfigObserver : public test::SendTest,
2214 public test::FakeEncoder {
2215 public:
2216 VideoCodecConfigObserver()
2217 : SendTest(kDefaultTimeoutMs),
2218 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002219 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002220 num_initializations_(0),
2221 stream_(nullptr) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002222
2223 private:
stefanff483612015-12-21 03:14:00 -08002224 void ModifyVideoConfigs(
2225 VideoSendStream::Config* send_config,
2226 std::vector<VideoReceiveStream::Config>* receive_configs,
2227 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002228 send_config->encoder_settings.encoder = this;
sprangf24a0642017-02-28 13:23:26 -08002229 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002230 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002231 }
2232
stefanff483612015-12-21 03:14:00 -08002233 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002234 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002235 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002236 stream_ = send_stream;
2237 }
2238
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002239 int32_t InitEncode(const VideoCodec* config,
2240 int32_t number_of_cores,
2241 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002242 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002243 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002244 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002245 } else {
2246 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002247 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002248 }
2249 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002250 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002251 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2252 }
2253
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002254 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002255 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002256 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002257
sprangf24a0642017-02-28 13:23:26 -08002258 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002259 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002260 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002261 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002262 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2263 "new encoder settings.";
2264 }
2265
sprangf24a0642017-02-28 13:23:26 -08002266 const uint32_t kFirstMaxBitrateBps = 1000000;
2267 const uint32_t kSecondMaxBitrateBps = 2000000;
2268
pbos14fe7082016-04-20 06:35:56 -07002269 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002270 size_t num_initializations_;
2271 VideoSendStream* stream_;
2272 VideoEncoderConfig encoder_config_;
2273 } test;
2274
stefane74eef12016-01-08 06:47:13 -08002275 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002276}
2277
Peter Boström53eda3d2015-03-27 15:53:18 +01002278static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
2279template <typename T>
2280class VideoCodecConfigObserver : public test::SendTest,
2281 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002282 public:
2283 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2284 const char* codec_name)
2285 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2286 FakeEncoder(Clock::GetRealTimeClock()),
2287 video_codec_type_(video_codec_type),
2288 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002289 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002290 num_initializations_(0),
2291 stream_(nullptr) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002292 memset(&encoder_settings_, 0, sizeof(encoder_settings_));
2293 }
2294
2295 private:
perkjfa10b552016-10-02 23:45:26 -07002296 class VideoStreamFactory
2297 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2298 public:
2299 VideoStreamFactory() {}
2300
2301 private:
2302 std::vector<VideoStream> CreateEncoderStreams(
2303 int width,
2304 int height,
2305 const VideoEncoderConfig& encoder_config) override {
2306 std::vector<VideoStream> streams =
2307 test::CreateVideoStreams(width, height, encoder_config);
2308 for (size_t i = 0; i < streams.size(); ++i) {
2309 streams[i].temporal_layer_thresholds_bps.resize(
2310 kVideoCodecConfigObserverNumberOfTemporalLayers - 1);
2311 }
2312 return streams;
2313 }
2314 };
2315
stefanff483612015-12-21 03:14:00 -08002316 void ModifyVideoConfigs(
2317 VideoSendStream::Config* send_config,
2318 std::vector<VideoReceiveStream::Config>* receive_configs,
2319 VideoEncoderConfig* encoder_config) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002320 send_config->encoder_settings.encoder = this;
2321 send_config->encoder_settings.payload_name = codec_name_;
2322
kthelgason29a44e32016-09-27 03:52:02 -07002323 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002324 encoder_config->video_stream_factory =
2325 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002326 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002327 }
2328
stefanff483612015-12-21 03:14:00 -08002329 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002330 VideoSendStream* send_stream,
2331 const std::vector<VideoReceiveStream*>& receive_streams) override {
2332 stream_ = send_stream;
2333 }
2334
2335 int32_t InitEncode(const VideoCodec* config,
2336 int32_t number_of_cores,
2337 size_t max_payload_size) override {
2338 EXPECT_EQ(video_codec_type_, config->codecType);
2339 VerifyCodecSpecifics(*config);
2340 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002341 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002342 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2343 }
2344
2345 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002346 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2347 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002348
2349 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002350 EXPECT_TRUE(
2351 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002352 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002353
2354 encoder_settings_.frameDroppingOn = true;
kthelgason29a44e32016-09-27 03:52:02 -07002355 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002356 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002357 ASSERT_TRUE(
2358 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002359 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002360 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2361 "new encoder settings.";
2362 }
2363
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002364 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002365 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002366 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002367 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2368 return 0;
2369 }
2370
2371 T encoder_settings_;
2372 const VideoCodecType video_codec_type_;
2373 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002374 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002375 size_t num_initializations_;
2376 VideoSendStream* stream_;
2377 VideoEncoderConfig encoder_config_;
2378};
2379
2380template <>
2381void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2382 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002383 EXPECT_EQ(
2384 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002385}
kthelgason29a44e32016-09-27 03:52:02 -07002386
2387template <>
2388rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2389VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2390 return new rtc::RefCountedObject<
2391 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2392}
2393
Peter Boström53eda3d2015-03-27 15:53:18 +01002394template <>
2395void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2396 const VideoCodec& config) const {
2397 // Check that the number of temporal layers has propagated properly to
2398 // VideoCodec.
2399 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002400 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002401
2402 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2403 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2404 config.simulcastStream[i].numberOfTemporalLayers);
2405 }
2406
2407 // Set expected temporal layers as they should have been set when
Erik Språng08127a92016-11-16 16:41:30 +01002408 // reconfiguring the encoder and not match the set config. Also copy the
2409 // TemporalLayersFactory pointer that has been injected by ViEEncoder.
Peter Boström53eda3d2015-03-27 15:53:18 +01002410 VideoCodecVP8 encoder_settings = encoder_settings_;
2411 encoder_settings.numberOfTemporalLayers =
2412 kVideoCodecConfigObserverNumberOfTemporalLayers;
Erik Språng08127a92016-11-16 16:41:30 +01002413 encoder_settings.tl_factory = config.VP8().tl_factory;
hta257dc392016-10-25 09:05:06 -07002414 EXPECT_EQ(
2415 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002416}
kthelgason29a44e32016-09-27 03:52:02 -07002417
2418template <>
2419rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2420VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2421 return new rtc::RefCountedObject<
2422 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2423}
2424
Peter Boström53eda3d2015-03-27 15:53:18 +01002425template <>
2426void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2427 const VideoCodec& config) const {
2428 // Check that the number of temporal layers has propagated properly to
2429 // VideoCodec.
2430 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002431 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002432
2433 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2434 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2435 config.simulcastStream[i].numberOfTemporalLayers);
2436 }
2437
2438 // Set expected temporal layers as they should have been set when
2439 // reconfiguring the encoder and not match the set config.
2440 VideoCodecVP9 encoder_settings = encoder_settings_;
2441 encoder_settings.numberOfTemporalLayers =
2442 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002443 EXPECT_EQ(
2444 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002445}
2446
kthelgason29a44e32016-09-27 03:52:02 -07002447template <>
2448rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2449VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2450 return new rtc::RefCountedObject<
2451 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2452}
2453
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002454TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002455 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002456 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002457}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002458
Peter Boström53eda3d2015-03-27 15:53:18 +01002459TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2460 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002461 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002462}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002463
Peter Boström53eda3d2015-03-27 15:53:18 +01002464TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2465 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002466 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002467}
2468
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002469TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002470 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002471 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002472 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2473 rtp_packets_sent_(0),
2474 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002475
2476 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002477 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002478 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002479 RTPHeader header;
2480 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002481 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002482 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2483 return SEND_PACKET;
2484 }
2485
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002486 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002487 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002488 test::RtcpPacketParser parser;
2489 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002490
danilchap3dc929e2016-11-02 08:21:59 -07002491 if (parser.sender_report()->num_packets() > 0) {
2492 // Only compare sent media bytes if SenderPacketCount matches the
2493 // number of sent rtp packets (a new rtp packet could be sent before
2494 // the rtcp packet).
2495 if (parser.sender_report()->sender_octet_count() > 0 &&
2496 parser.sender_report()->sender_packet_count() ==
2497 rtp_packets_sent_) {
2498 EXPECT_EQ(media_bytes_sent_,
2499 parser.sender_report()->sender_octet_count());
2500 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002501 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002502 }
2503
2504 return SEND_PACKET;
2505 }
2506
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002507 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002508 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002509 }
2510
stefan4b569042015-11-11 06:39:57 -08002511 rtc::CriticalSection crit_;
2512 size_t rtp_packets_sent_ GUARDED_BY(&crit_);
2513 size_t media_bytes_sent_ GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002514 } test;
2515
stefane74eef12016-01-08 06:47:13 -08002516 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002517}
2518
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002519TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
2520 static const int kScreencastTargetBitrateKbps = 200;
perkjfa10b552016-10-02 23:45:26 -07002521
2522 class VideoStreamFactory
2523 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2524 public:
2525 VideoStreamFactory() {}
2526
2527 private:
2528 std::vector<VideoStream> CreateEncoderStreams(
2529 int width,
2530 int height,
2531 const VideoEncoderConfig& encoder_config) override {
2532 std::vector<VideoStream> streams =
2533 test::CreateVideoStreams(width, height, encoder_config);
2534 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
2535 streams[0].temporal_layer_thresholds_bps.push_back(
2536 kScreencastTargetBitrateKbps * 1000);
2537 return streams;
2538 }
2539 };
2540
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002541 class ScreencastTargetBitrateTest : public test::SendTest,
2542 public test::FakeEncoder {
2543 public:
2544 ScreencastTargetBitrateTest()
2545 : SendTest(kDefaultTimeoutMs),
2546 test::FakeEncoder(Clock::GetRealTimeClock()) {}
2547
2548 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002549 int32_t InitEncode(const VideoCodec* config,
2550 int32_t number_of_cores,
2551 size_t max_payload_size) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002552 EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps),
2553 config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002554 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002555 return test::FakeEncoder::InitEncode(
2556 config, number_of_cores, max_payload_size);
2557 }
stefanff483612015-12-21 03:14:00 -08002558 void ModifyVideoConfigs(
2559 VideoSendStream::Config* send_config,
2560 std::vector<VideoReceiveStream::Config>* receive_configs,
2561 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002562 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002563 EXPECT_EQ(1u, encoder_config->number_of_streams);
2564 encoder_config->video_stream_factory =
2565 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002566 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002567 }
2568
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002569 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002570 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002571 << "Timed out while waiting for the encoder to be initialized.";
2572 }
2573 } test;
2574
stefane74eef12016-01-08 06:47:13 -08002575 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002576}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002577
philipelc6957c72016-04-28 15:52:49 +02002578TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002579 // These are chosen to be "kind of odd" to not be accidentally checked against
2580 // default values.
2581 static const int kMinBitrateKbps = 137;
2582 static const int kStartBitrateKbps = 345;
2583 static const int kLowerMaxBitrateKbps = 312;
2584 static const int kMaxBitrateKbps = 413;
2585 static const int kIncreasedStartBitrateKbps = 451;
2586 static const int kIncreasedMaxBitrateKbps = 597;
2587 class EncoderBitrateThresholdObserver : public test::SendTest,
2588 public test::FakeEncoder {
2589 public:
2590 EncoderBitrateThresholdObserver()
2591 : SendTest(kDefaultTimeoutMs),
2592 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002593 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002594 bitrate_changed_event_(false, false),
2595 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002596 num_initializations_(0),
2597 call_(nullptr),
2598 send_stream_(nullptr) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002599
2600 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002601 int32_t InitEncode(const VideoCodec* codecSettings,
2602 int32_t numberOfCores,
2603 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002604 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2605 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002606 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002607 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2608 codecSettings->minBitrate);
2609 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2610 codecSettings->startBitrate);
2611 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2612 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002613 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002614 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002615 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2616 codecSettings->maxBitrate);
2617 // The start bitrate should be kept (-1) and capped to the max bitrate.
2618 // Since this is not an end-to-end call no receiver should have been
2619 // returning a REMB that could lower this estimate.
2620 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002621 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002622 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2623 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002624 // The start bitrate will be whatever the rate BitRateController
2625 // has currently configured but in the span of the set max and min
2626 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002627 }
2628 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002629 init_encode_event_.Set();
2630
pbos@webrtc.org00873182014-11-25 14:03:34 +00002631 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2632 maxPayloadSize);
2633 }
2634
Erik Språng08127a92016-11-16 16:41:30 +01002635 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
2636 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002637 {
2638 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002639 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2640 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002641 }
Erik Språng08127a92016-11-16 16:41:30 +01002642 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002643 }
2644 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002645 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002646 }
2647
2648 void WaitForSetRates(uint32_t expected_bitrate) {
2649 EXPECT_TRUE(
2650 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2651 << "Timed out while waiting encoder rate to be set.";
2652 rtc::CritScope lock(&crit_);
2653 EXPECT_EQ(expected_bitrate, target_bitrate_);
2654 }
2655
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002656 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07002657 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01002658 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2659 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2660 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002661 return config;
2662 }
2663
perkjfa10b552016-10-02 23:45:26 -07002664 class VideoStreamFactory
2665 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2666 public:
2667 explicit VideoStreamFactory(int min_bitrate_bps)
2668 : min_bitrate_bps_(min_bitrate_bps) {}
2669
2670 private:
2671 std::vector<VideoStream> CreateEncoderStreams(
2672 int width,
2673 int height,
2674 const VideoEncoderConfig& encoder_config) override {
2675 std::vector<VideoStream> streams =
2676 test::CreateVideoStreams(width, height, encoder_config);
2677 streams[0].min_bitrate_bps = min_bitrate_bps_;
2678 return streams;
2679 }
2680
2681 const int min_bitrate_bps_;
2682 };
2683
stefanff483612015-12-21 03:14:00 -08002684 void ModifyVideoConfigs(
2685 VideoSendStream::Config* send_config,
2686 std::vector<VideoReceiveStream::Config>* receive_configs,
2687 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002688 send_config->encoder_settings.encoder = this;
2689 // Set bitrates lower/higher than min/max to make sure they are properly
2690 // capped.
perkjfa10b552016-10-02 23:45:26 -07002691 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2692 // Create a new StreamFactory to be able to set
2693 // |VideoStream.min_bitrate_bps|.
2694 encoder_config->video_stream_factory =
2695 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002696 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002697 }
2698
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002699 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002700 call_ = sender_call;
2701 }
2702
stefanff483612015-12-21 03:14:00 -08002703 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002704 VideoSendStream* send_stream,
2705 const std::vector<VideoReceiveStream*>& receive_streams) override {
2706 send_stream_ = send_stream;
2707 }
2708
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002709 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002710 ASSERT_TRUE(
2711 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002712 << "Timed out while waiting for encoder to be configured.";
2713 WaitForSetRates(kStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002714 Call::Config::BitrateConfig bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002715 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2716 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2717 call_->SetBitrateConfig(bitrate_config);
perkj26091b12016-09-01 01:17:40 -07002718 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2719 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002720 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002721 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002722 ASSERT_TRUE(
2723 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002724 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002725 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002726 WaitForSetRates(kLowerMaxBitrateKbps);
2727
2728 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2729 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2730 ASSERT_TRUE(
2731 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002732 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002733 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002734 // Expected target bitrate is the start bitrate set in the call to
2735 // call_->SetBitrateConfig.
2736 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002737 }
2738
pbos14fe7082016-04-20 06:35:56 -07002739 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002740 rtc::Event bitrate_changed_event_;
2741 rtc::CriticalSection crit_;
2742 uint32_t target_bitrate_ GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002743
pbos@webrtc.org00873182014-11-25 14:03:34 +00002744 int num_initializations_;
2745 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002746 webrtc::VideoSendStream* send_stream_;
2747 webrtc::VideoEncoderConfig encoder_config_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002748 } test;
2749
stefane74eef12016-01-08 06:47:13 -08002750 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002751}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002752
2753TEST_F(VideoSendStreamTest, ReportsSentResolution) {
2754 static const size_t kNumStreams = 3;
2755 // Unusual resolutions to make sure that they are the ones being reported.
2756 static const struct {
2757 int width;
2758 int height;
2759 } kEncodedResolution[kNumStreams] = {
2760 {241, 181}, {300, 121}, {121, 221}};
2761 class ScreencastTargetBitrateTest : public test::SendTest,
2762 public test::FakeEncoder {
2763 public:
2764 ScreencastTargetBitrateTest()
2765 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002766 test::FakeEncoder(Clock::GetRealTimeClock()),
2767 send_stream_(nullptr) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002768
2769 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002770 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002771 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002772 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002773 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002774 specifics.codecType = kVideoCodecGeneric;
2775
2776 uint8_t buffer[16] = {0};
2777 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
2778 encoded._timeStamp = input_image.timestamp();
2779 encoded.capture_time_ms_ = input_image.render_time_ms();
2780
2781 for (size_t i = 0; i < kNumStreams; ++i) {
2782 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
2783 encoded._frameType = (*frame_types)[i];
2784 encoded._encodedWidth = kEncodedResolution[i].width;
2785 encoded._encodedHeight = kEncodedResolution[i].height;
brandtre78d2662017-01-16 05:57:16 -08002786 EncodedImageCallback* callback;
2787 {
2788 rtc::CritScope cs(&crit_sect_);
2789 callback = callback_;
2790 }
2791 RTC_DCHECK(callback);
2792 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07002793 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002794 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07002795 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002796 }
2797
Peter Boström5811a392015-12-10 13:02:50 +01002798 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002799 return 0;
2800 }
stefanff483612015-12-21 03:14:00 -08002801 void ModifyVideoConfigs(
2802 VideoSendStream::Config* send_config,
2803 std::vector<VideoReceiveStream::Config>* receive_configs,
2804 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002805 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002806 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002807 }
2808
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002809 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002810
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002811 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002812 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002813 << "Timed out while waiting for the encoder to send one frame.";
2814 VideoSendStream::Stats stats = send_stream_->GetStats();
2815
2816 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002817 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002818 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002819 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002820 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002821 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002822 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002823 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
2824 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002825 }
2826 }
2827
stefanff483612015-12-21 03:14:00 -08002828 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002829 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002830 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002831 send_stream_ = send_stream;
2832 }
2833
2834 VideoSendStream* send_stream_;
2835 } test;
2836
stefane74eef12016-01-08 06:47:13 -08002837 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002838}
philipel0f9af012015-09-01 07:01:51 -07002839
Peter Boström12996152016-05-14 02:03:18 +02002840#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01002841class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07002842 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01002843 Vp9HeaderObserver()
2844 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
philipel7fabd462015-09-03 04:42:32 -07002845 vp9_encoder_(VP9Encoder::Create()),
Åsa Perssonff24c042015-12-04 10:58:08 +01002846 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
2847 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07002848 frames_sent_(0),
2849 expected_width_(0),
2850 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07002851
stefanff483612015-12-21 03:14:00 -08002852 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07002853 VideoSendStream::Config* send_config,
2854 std::vector<VideoReceiveStream::Config>* receive_configs,
2855 VideoEncoderConfig* encoder_config) {}
2856
Åsa Perssonff24c042015-12-04 10:58:08 +01002857 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07002858
2859 private:
minyue20c84cc2017-04-10 16:57:57 -07002860 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07002861
perkjfa10b552016-10-02 23:45:26 -07002862 class VideoStreamFactory
2863 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2864 public:
2865 explicit VideoStreamFactory(size_t number_of_temporal_layers)
2866 : number_of_temporal_layers_(number_of_temporal_layers) {}
2867
2868 private:
2869 std::vector<VideoStream> CreateEncoderStreams(
2870 int width,
2871 int height,
2872 const VideoEncoderConfig& encoder_config) override {
2873 std::vector<VideoStream> streams =
2874 test::CreateVideoStreams(width, height, encoder_config);
2875 streams[0].temporal_layer_thresholds_bps.resize(
2876 number_of_temporal_layers_ - 1);
2877 return streams;
2878 }
2879
2880 const size_t number_of_temporal_layers_;
2881 };
2882
stefanff483612015-12-21 03:14:00 -08002883 void ModifyVideoConfigs(
2884 VideoSendStream::Config* send_config,
2885 std::vector<VideoReceiveStream::Config>* receive_configs,
2886 VideoEncoderConfig* encoder_config) override {
philipel7fabd462015-09-03 04:42:32 -07002887 send_config->encoder_settings.encoder = vp9_encoder_.get();
philipel0f9af012015-09-01 07:01:51 -07002888 send_config->encoder_settings.payload_name = "VP9";
2889 send_config->encoder_settings.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08002890 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07002891 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
2892 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07002893 EXPECT_EQ(1u, encoder_config->number_of_streams);
2894 encoder_config->video_stream_factory =
2895 new rtc::RefCountedObject<VideoStreamFactory>(
2896 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07002897 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07002898 }
2899
perkjfa10b552016-10-02 23:45:26 -07002900 void ModifyVideoCaptureStartResolution(int* width,
2901 int* height,
2902 int* frame_rate) override {
2903 expected_width_ = *width;
2904 expected_height_ = *height;
2905 }
2906
philipel0f9af012015-09-01 07:01:51 -07002907 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002908 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
2909 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002910 }
2911
2912 Action OnSendRtp(const uint8_t* packet, size_t length) override {
2913 RTPHeader header;
2914 EXPECT_TRUE(parser_->Parse(packet, length, &header));
2915
Åsa Perssonff24c042015-12-04 10:58:08 +01002916 EXPECT_EQ(kVp9PayloadType, header.payloadType);
2917 const uint8_t* payload = packet + header.headerLength;
2918 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07002919
Åsa Perssonff24c042015-12-04 10:58:08 +01002920 bool new_packet = packets_sent_ == 0 ||
2921 IsNewerSequenceNumber(header.sequenceNumber,
2922 last_header_.sequenceNumber);
2923 if (payload_length > 0 && new_packet) {
2924 RtpDepacketizer::ParsedPayload parsed;
2925 RtpDepacketizerVp9 depacketizer;
2926 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
2927 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
2928 // Verify common fields for all configurations.
2929 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
2930 CompareConsecutiveFrames(header, parsed.type.Video);
2931 // Verify configuration specific settings.
2932 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07002933
Åsa Perssonff24c042015-12-04 10:58:08 +01002934 ++packets_sent_;
2935 if (header.markerBit) {
2936 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002937 }
Åsa Perssonff24c042015-12-04 10:58:08 +01002938 last_header_ = header;
2939 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07002940 }
philipel0f9af012015-09-01 07:01:51 -07002941 return SEND_PACKET;
2942 }
2943
philipel7fabd462015-09-03 04:42:32 -07002944 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01002945 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
2946 if (last_vp9_.picture_id > vp9.picture_id) {
2947 return vp9.picture_id == 0; // Wrap.
2948 } else {
2949 return vp9.picture_id == last_vp9_.picture_id + 1;
2950 }
2951 }
2952
2953 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01002954 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
2955 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
2956 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
2957 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
2958 vp9.spatial_idx);
2959 }
2960
2961 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
2962 uint8_t num_layers) const {
2963 switch (num_layers) {
2964 case 0:
2965 VerifyTemporalLayerStructure0(vp9);
2966 break;
2967 case 1:
2968 VerifyTemporalLayerStructure1(vp9);
2969 break;
2970 case 2:
2971 VerifyTemporalLayerStructure2(vp9);
2972 break;
2973 case 3:
2974 VerifyTemporalLayerStructure3(vp9);
2975 break;
2976 default:
2977 RTC_NOTREACHED();
2978 }
2979 }
2980
2981 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
2982 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
2983 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
2984 EXPECT_FALSE(vp9.temporal_up_switch);
2985 }
2986
2987 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
2988 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2989 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
2990 EXPECT_FALSE(vp9.temporal_up_switch);
2991 }
2992
2993 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
2994 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2995 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
2996 EXPECT_LE(vp9.temporal_idx, 1);
2997 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
2998 if (IsNewPictureId(vp9)) {
2999 uint8_t expected_tid =
3000 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
3001 EXPECT_EQ(expected_tid, vp9.temporal_idx);
3002 }
3003 }
3004
3005 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
3006 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
3007 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
3008 EXPECT_LE(vp9.temporal_idx, 2);
3009 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
3010 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
3011 switch (vp9.temporal_idx) {
3012 case 0:
3013 EXPECT_EQ(2, last_vp9_.temporal_idx);
3014 EXPECT_FALSE(vp9.temporal_up_switch);
3015 break;
3016 case 1:
3017 EXPECT_EQ(2, last_vp9_.temporal_idx);
3018 EXPECT_TRUE(vp9.temporal_up_switch);
3019 break;
3020 case 2:
3021 EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
3022 break;
3023 }
3024 }
3025 }
3026
3027 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
3028 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
3029 return;
3030
3031 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
3032 if (vp9.temporal_idx == 0)
3033 ++expected_tl0_idx;
3034 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
3035 }
3036
3037 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
3038 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
3039 }
3040
3041 // Flexible mode (F=1): Non-flexible mode (F=0):
3042 //
3043 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3044 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
3045 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3046 // I: |M| PICTURE ID | I: |M| PICTURE ID |
3047 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3048 // M: | EXTENDED PID | M: | EXTENDED PID |
3049 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3050 // L: | T |U| S |D| L: | T |U| S |D|
3051 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3052 // P,F: | P_DIFF |X|N| | TL0PICIDX |
3053 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3054 // X: |EXTENDED P_DIFF| V: | SS .. |
3055 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
3056 // V: | SS .. |
3057 // +-+-+-+-+-+-+-+-+
3058 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
3059 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
3060 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
3061 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
3062 EXPECT_GE(vp9.spatial_idx, 0); // S
3063 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3064 if (vp9.ss_data_available) // V
3065 VerifySsData(vp9);
3066
3067 if (frames_sent_ == 0)
3068 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3069
3070 if (!vp9.inter_pic_predicted) {
3071 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3072 EXPECT_FALSE(vp9.temporal_up_switch);
3073 }
3074 }
3075
3076 // Scalability structure (SS).
3077 //
3078 // +-+-+-+-+-+-+-+-+
3079 // V: | N_S |Y|G|-|-|-|
3080 // +-+-+-+-+-+-+-+-+
3081 // Y: | WIDTH | N_S + 1 times
3082 // +-+-+-+-+-+-+-+-+
3083 // | HEIGHT |
3084 // +-+-+-+-+-+-+-+-+
3085 // G: | N_G |
3086 // +-+-+-+-+-+-+-+-+
3087 // N_G: | T |U| R |-|-| N_G times
3088 // +-+-+-+-+-+-+-+-+
3089 // | P_DIFF | R times
3090 // +-+-+-+-+-+-+-+-+
3091 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3092 EXPECT_TRUE(vp9.ss_data_available); // V
3093 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3094 vp9.num_spatial_layers);
3095 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003096 int expected_width = expected_width_;
3097 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003098 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003099 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3100 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3101 expected_width /= 2;
3102 expected_height /= 2;
3103 }
3104 }
3105
3106 void CompareConsecutiveFrames(const RTPHeader& header,
3107 const RTPVideoHeader& video) const {
3108 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
3109
3110 bool new_frame = packets_sent_ == 0 ||
3111 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003112 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003113 if (!new_frame) {
3114 EXPECT_FALSE(last_header_.markerBit);
3115 EXPECT_EQ(last_header_.timestamp, header.timestamp);
3116 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
3117 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
3118 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
3119 VerifySpatialIdxWithinFrame(vp9);
3120 return;
3121 }
3122 // New frame.
3123 EXPECT_TRUE(vp9.beginning_of_frame);
3124
3125 // Compare with last packet in previous frame.
3126 if (frames_sent_ == 0)
3127 return;
3128 EXPECT_TRUE(last_vp9_.end_of_frame);
3129 EXPECT_TRUE(last_header_.markerBit);
3130 EXPECT_TRUE(ContinuousPictureId(vp9));
3131 VerifyTl0Idx(vp9);
3132 }
3133
kwiberg27f982b2016-03-01 11:52:33 -08003134 std::unique_ptr<VP9Encoder> vp9_encoder_;
philipel0f9af012015-09-01 07:01:51 -07003135 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003136 webrtc::VideoEncoderConfig encoder_config_;
3137 RTPHeader last_header_;
3138 RTPVideoHeaderVP9 last_vp9_;
3139 size_t packets_sent_;
3140 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003141 int expected_width_;
3142 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003143};
3144
Åsa Perssonff24c042015-12-04 10:58:08 +01003145TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
3146 const uint8_t kNumTemporalLayers = 1;
3147 const uint8_t kNumSpatialLayers = 1;
3148 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3149}
3150
3151TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
3152 const uint8_t kNumTemporalLayers = 2;
3153 const uint8_t kNumSpatialLayers = 1;
3154 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3155}
3156
3157TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
3158 const uint8_t kNumTemporalLayers = 3;
3159 const uint8_t kNumSpatialLayers = 1;
3160 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3161}
3162
3163TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
3164 const uint8_t kNumTemporalLayers = 1;
3165 const uint8_t kNumSpatialLayers = 2;
3166 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3167}
3168
3169TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3170 const uint8_t kNumTemporalLayers = 2;
3171 const uint8_t kNumSpatialLayers = 2;
3172 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3173}
3174
3175TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3176 const uint8_t kNumTemporalLayers = 3;
3177 const uint8_t kNumSpatialLayers = 2;
3178 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3179}
3180
3181void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3182 uint8_t num_spatial_layers) {
3183 static const size_t kNumFramesToSend = 100;
3184 // Set to < kNumFramesToSend and coprime to length of temporal layer
3185 // structures to verify temporal id reset on key frame.
3186 static const int kKeyFrameInterval = 31;
3187 class NonFlexibleMode : public Vp9HeaderObserver {
3188 public:
3189 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3190 : num_temporal_layers_(num_temporal_layers),
3191 num_spatial_layers_(num_spatial_layers),
3192 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
stefanff483612015-12-21 03:14:00 -08003193 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003194 VideoSendStream::Config* send_config,
3195 std::vector<VideoReceiveStream::Config>* receive_configs,
3196 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003197 vp9_settings_.flexibleMode = false;
3198 vp9_settings_.frameDroppingOn = false;
3199 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3200 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3201 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003202 }
3203
Åsa Perssonff24c042015-12-04 10:58:08 +01003204 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
3205 bool ss_data_expected = !vp9.inter_pic_predicted &&
3206 vp9.beginning_of_frame && vp9.spatial_idx == 0;
3207 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
3208 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted); // D
asapersson38bb8ad2015-12-14 01:41:19 -08003209 EXPECT_EQ(!vp9.inter_pic_predicted,
3210 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003211
3212 if (IsNewPictureId(vp9)) {
3213 EXPECT_EQ(0, vp9.spatial_idx);
3214 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
3215 }
3216
3217 VerifyFixedTemporalLayerStructure(vp9,
3218 l_field_ ? num_temporal_layers_ : 0);
3219
3220 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003221 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003222 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003223 const uint8_t num_temporal_layers_;
3224 const uint8_t num_spatial_layers_;
3225 const bool l_field_;
3226 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003227
stefane74eef12016-01-08 06:47:13 -08003228 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003229}
3230
asaperssond9f641e2016-01-21 01:11:35 -08003231TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3232 static const size_t kNumFramesToSend = 50;
3233 static const int kWidth = 4;
3234 static const int kHeight = 4;
3235 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3236 void ModifyVideoConfigsHook(
3237 VideoSendStream::Config* send_config,
3238 std::vector<VideoReceiveStream::Config>* receive_configs,
3239 VideoEncoderConfig* encoder_config) override {
3240 vp9_settings_.flexibleMode = false;
3241 vp9_settings_.numberOfTemporalLayers = 1;
3242 vp9_settings_.numberOfSpatialLayers = 1;
3243
perkjfa10b552016-10-02 23:45:26 -07003244 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003245 }
3246
3247 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3248 if (frames_sent_ > kNumFramesToSend)
3249 observation_complete_.Set();
3250 }
perkjfa10b552016-10-02 23:45:26 -07003251
3252 void ModifyVideoCaptureStartResolution(int* width,
3253 int* height,
3254 int* frame_rate) override {
3255 expected_width_ = kWidth;
3256 expected_height_ = kHeight;
3257 *width = kWidth;
3258 *height = kHeight;
3259 }
asaperssond9f641e2016-01-21 01:11:35 -08003260 } test;
3261
3262 RunBaseTest(&test);
3263}
3264
kjellanderf9e2a362017-03-24 12:17:33 -07003265#if defined(WEBRTC_ANDROID)
3266// Crashes on Android; bugs.webrtc.org/7401
3267#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3268#else
3269#define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
3270#endif
3271TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003272 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003273 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003274 VideoSendStream::Config* send_config,
3275 std::vector<VideoReceiveStream::Config>* receive_configs,
3276 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003277 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003278 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003279 vp9_settings_.numberOfTemporalLayers = 1;
3280 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003281 }
3282
Åsa Perssonff24c042015-12-04 10:58:08 +01003283 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3284 EXPECT_TRUE(vp9_header.flexible_mode);
3285 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3286 if (vp9_header.inter_pic_predicted) {
3287 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003288 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003289 }
3290 }
3291 } test;
3292
stefane74eef12016-01-08 06:47:13 -08003293 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003294}
Peter Boström12996152016-05-14 02:03:18 +02003295#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003296
perkj803d97f2016-11-01 11:45:46 -07003297void VideoSendStreamTest::TestRequestSourceRotateVideo(
3298 bool support_orientation_ext) {
philipel4fb651d2017-04-10 03:54:05 -07003299 CreateSenderCall(Call::Config(event_log_.get()));
perkj803d97f2016-11-01 11:45:46 -07003300
3301 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003302 CreateSendConfig(1, 0, 0, &transport);
perkj803d97f2016-11-01 11:45:46 -07003303 video_send_config_.rtp.extensions.clear();
3304 if (support_orientation_ext) {
3305 video_send_config_.rtp.extensions.push_back(
3306 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3307 }
3308
3309 CreateVideoStreams();
3310 test::FrameForwarder forwarder;
3311 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07003312 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
perkj803d97f2016-11-01 11:45:46 -07003313
3314 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3315 support_orientation_ext);
3316
3317 DestroyStreams();
3318}
3319
3320TEST_F(VideoSendStreamTest,
3321 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3322 TestRequestSourceRotateVideo(false);
3323}
3324
3325TEST_F(VideoSendStreamTest,
3326 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3327 TestRequestSourceRotateVideo(true);
3328}
3329
michaelta3328772016-11-29 09:25:03 -08003330// This test verifies that overhead is removed from the bandwidth estimate by
3331// testing that the maximum possible target payload rate is smaller than the
3332// maximum bandwidth estimate by the overhead rate.
michaelt273f31b2017-02-08 08:21:52 -08003333TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003334 test::ScopedFieldTrials override_field_trials(
3335 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3336 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3337 public test::FakeEncoder {
3338 public:
3339 RemoveOverheadFromBandwidthTest()
3340 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3341 FakeEncoder(Clock::GetRealTimeClock()),
3342 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003343 max_bitrate_bps_(0),
3344 first_packet_sent_(false),
3345 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003346
3347 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
3348 uint32_t frameRate) override {
3349 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003350 // Wait for the first sent packet so that videosendstream knows
3351 // rtp_overhead.
3352 if (first_packet_sent_) {
3353 max_bitrate_bps_ = bitrate.get_sum_bps();
3354 bitrate_changed_event_.Set();
3355 }
michaelta3328772016-11-29 09:25:03 -08003356 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3357 }
3358
3359 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3360 call_ = sender_call;
3361 }
3362
3363 void ModifyVideoConfigs(
3364 VideoSendStream::Config* send_config,
3365 std::vector<VideoReceiveStream::Config>* receive_configs,
3366 VideoEncoderConfig* encoder_config) override {
3367 send_config->rtp.max_packet_size = 1200;
3368 send_config->encoder_settings.encoder = this;
3369 EXPECT_FALSE(send_config->rtp.extensions.empty());
3370 }
3371
michaelt192132e2017-01-26 09:05:27 -08003372 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3373 rtc::CritScope lock(&crit_);
3374 first_packet_sent_ = true;
3375 return SEND_PACKET;
3376 }
3377
michaelta3328772016-11-29 09:25:03 -08003378 void PerformTest() override {
michaelta3328772016-11-29 09:25:03 -08003379 Call::Config::BitrateConfig bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003380 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003381 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003382 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003383 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3384 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003385 bitrate_config.min_bitrate_bps = kMinBitrateBps;
michaelta3328772016-11-29 09:25:03 -08003386 call_->SetBitrateConfig(bitrate_config);
michaelt273f31b2017-02-08 08:21:52 -08003387 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
michaelta3328772016-11-29 09:25:03 -08003388
3389 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003390 // overhead of 40B per packet video produces 2240bps overhead.
3391 // So the encoder BW should be set to 57760bps.
3392 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
michaelta3328772016-11-29 09:25:03 -08003393 {
3394 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003395 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003396 }
3397 }
3398
3399 private:
3400 Call* call_;
3401 rtc::CriticalSection crit_;
michaelt192132e2017-01-26 09:05:27 -08003402 uint32_t max_bitrate_bps_ GUARDED_BY(&crit_);
3403 bool first_packet_sent_ GUARDED_BY(&crit_);
3404 rtc::Event bitrate_changed_event_;
michaelta3328772016-11-29 09:25:03 -08003405 } test;
3406
3407 RunBaseTest(&test);
3408}
3409
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003410} // namespace webrtc