blob: 340c71c7bfc78896a6f5714897d65229744bb2de [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) {
299 class VideoRotationObserver : public test::SendTest {
300 public:
301 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
302 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
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000340class FakeReceiveStatistics : public NullReceiveStatistics {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000341 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000342 FakeReceiveStatistics(uint32_t send_ssrc,
343 uint32_t last_sequence_number,
344 uint32_t cumulative_lost,
345 uint8_t fraction_lost)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000346 : lossy_stats_(new LossyStatistician(last_sequence_number,
347 cumulative_lost,
348 fraction_lost)) {
349 stats_map_[send_ssrc] = lossy_stats_.get();
350 }
351
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000352 StatisticianMap GetActiveStatisticians() const override { return stats_map_; }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000353
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000354 StreamStatistician* GetStatistician(uint32_t ssrc) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000355 return lossy_stats_.get();
356 }
357
358 private:
359 class LossyStatistician : public StreamStatistician {
360 public:
361 LossyStatistician(uint32_t extended_max_sequence_number,
362 uint32_t cumulative_lost,
363 uint8_t fraction_lost) {
364 stats_.fraction_lost = fraction_lost;
365 stats_.cumulative_lost = cumulative_lost;
366 stats_.extended_max_sequence_number = extended_max_sequence_number;
367 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000368 bool GetStatistics(RtcpStatistics* statistics, bool reset) override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000369 *statistics = stats_;
370 return true;
371 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000372 void GetDataCounters(size_t* bytes_received,
373 uint32_t* packets_received) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000374 *bytes_received = 0;
375 *packets_received = 0;
376 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000377 void GetReceiveStreamDataCounters(
378 StreamDataCounters* data_counters) const override {}
379 uint32_t BitrateReceived() const override { return 0; }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000380 bool IsRetransmitOfOldPacket(const RTPHeader& header,
381 int64_t min_rtt) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000382 return false;
383 }
384
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000385 bool IsPacketInOrder(uint16_t sequence_number) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000386 return true;
387 }
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000388
389 RtcpStatistics stats_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000390 };
391
kwiberg27f982b2016-03-01 11:52:33 -0800392 std::unique_ptr<LossyStatistician> lossy_stats_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000393 StatisticianMap stats_map_;
394};
395
brandtre602f0a2016-10-31 03:40:49 -0700396class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100397 public:
brandtre602f0a2016-10-31 03:40:49 -0700398 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800399 bool use_nack,
400 bool expect_red,
401 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800402 const std::string& codec,
403 VideoEncoder* encoder)
brandtr20d45472017-01-02 00:34:27 -0800404 : EndToEndTest(kTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800405 encoder_(encoder),
Peter Boström39593972016-02-15 11:27:15 +0100406 payload_name_(codec),
407 use_nack_(use_nack),
408 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700409 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800410 sent_media_(false),
411 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800412 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100413
brandtr20d45472017-01-02 00:34:27 -0800414 // Some of the test cases are expected to time out and thus we are using
415 // a shorter timeout window than the default here.
416 static constexpr size_t kTimeoutMs = 10000;
417
Stefan Holmer4654d202015-12-08 09:10:43 +0100418 private:
419 Action OnSendRtp(const uint8_t* packet, size_t length) override {
420 RTPHeader header;
421 EXPECT_TRUE(parser_->Parse(packet, length, &header));
422
Stefan Holmer4654d202015-12-08 09:10:43 +0100423 int encapsulated_payload_type = -1;
424 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100425 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100426 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
427 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100428 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100429 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
430 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100431 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100432 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100433 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
434 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100435 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
436 length) {
437 // Not padding-only, media received outside of RED.
438 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800439 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100440 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100441 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000442
Stefan Holmer4654d202015-12-08 09:10:43 +0100443 if (header_extensions_enabled_) {
444 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
445 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
446 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
447 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
448 // 24 bits wrap.
449 EXPECT_GT(prev_header_.extension.absoluteSendTime,
450 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000451 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100452 EXPECT_GE(header.extension.absoluteSendTime,
453 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200454 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100455 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
456 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
457 prev_header_.extension.transportSequenceNumber;
458 EXPECT_EQ(1, seq_num_diff);
459 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200460
Stefan Holmer4654d202015-12-08 09:10:43 +0100461 if (encapsulated_payload_type != -1) {
462 if (encapsulated_payload_type ==
463 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700464 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800465 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100466 } else {
brandtr65a1e772016-12-12 01:54:58 -0800467 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000468 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000469 }
470
brandtr20d45472017-01-02 00:34:27 -0800471 if (sent_media_ && sent_ulpfec_) {
472 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100473 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000474
Stefan Holmer4654d202015-12-08 09:10:43 +0100475 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000476
Stefan Holmer4654d202015-12-08 09:10:43 +0100477 return SEND_PACKET;
478 }
479
Peter Boström39593972016-02-15 11:27:15 +0100480 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
481 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
482 // Configure some network delay.
483 const int kNetworkDelayMs = 100;
484 FakeNetworkPipe::Config config;
brandtr65a1e772016-12-12 01:54:58 -0800485 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100486 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700487 return new test::PacketTransport(
488 sender_call, this, test::PacketTransport::kSender,
489 VideoSendStreamTest::payload_type_map_, config);
Peter Boström39593972016-02-15 11:27:15 +0100490 }
491
stefanff483612015-12-21 03:14:00 -0800492 void ModifyVideoConfigs(
493 VideoSendStream::Config* send_config,
494 std::vector<VideoReceiveStream::Config>* receive_configs,
495 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100496 if (use_nack_) {
497 send_config->rtp.nack.rtp_history_ms =
498 (*receive_configs)[0].rtp.nack.rtp_history_ms =
499 VideoSendStreamTest::kNackRtpHistoryMs;
500 }
brandtr696c9c62016-12-19 05:47:28 -0800501 send_config->encoder_settings.encoder = encoder_;
Peter Boström39593972016-02-15 11:27:15 +0100502 send_config->encoder_settings.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700503 send_config->rtp.ulpfec.red_payload_type =
504 VideoSendStreamTest::kRedPayloadType;
505 send_config->rtp.ulpfec.ulpfec_payload_type =
506 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800507 EXPECT_FALSE(send_config->rtp.extensions.empty());
508 if (!header_extensions_enabled_) {
509 send_config->rtp.extensions.clear();
510 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100511 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700512 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100513 }
brandtrb5f2c3f2016-10-04 23:28:39 -0700514 (*receive_configs)[0].rtp.ulpfec.red_payload_type =
515 send_config->rtp.ulpfec.red_payload_type;
516 (*receive_configs)[0].rtp.ulpfec.ulpfec_payload_type =
517 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100518 }
519
520 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800521 EXPECT_EQ(expect_ulpfec_, Wait())
522 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100523 }
524
brandtr696c9c62016-12-19 05:47:28 -0800525 VideoEncoder* const encoder_;
526 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100527 const bool use_nack_;
528 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700529 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800530 bool sent_media_;
531 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100532 bool header_extensions_enabled_;
533 RTPHeader prev_header_;
534};
535
brandtre602f0a2016-10-31 03:40:49 -0700536TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800537 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
538 UlpfecObserver test(true, false, true, true, "VP8", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800539 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100540}
541
brandtre602f0a2016-10-31 03:40:49 -0700542TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800543 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
544 UlpfecObserver test(false, false, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100545 RunBaseTest(&test);
546}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000547
Peter Boström39593972016-02-15 11:27:15 +0100548// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
549// since we'll still have to re-request FEC packets, effectively wasting
550// bandwidth since the receiver has to wait for FEC retransmissions to determine
551// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700552TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800553 std::unique_ptr<VideoEncoder> encoder(
554 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
555 UlpfecObserver test(false, true, true, false, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100556 RunBaseTest(&test);
557}
558
559// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800560TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800561 std::unique_ptr<VideoEncoder> encoder(
562 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
563 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100564 RunBaseTest(&test);
565}
566
danilchap9f5b6222017-03-02 06:22:21 -0800567// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
568TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800569 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
570 UlpfecObserver test(false, true, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100571 RunBaseTest(&test);
572}
573
Peter Boström12996152016-05-14 02:03:18 +0200574#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800575// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
576TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800577 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
578 UlpfecObserver test(false, true, true, true, "VP9", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800579 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000580}
Peter Boström12996152016-05-14 02:03:18 +0200581#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000582
brandtre78d2662017-01-16 05:57:16 -0800583TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800584 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800585 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800586 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
587 RunBaseTest(&test);
588}
589
brandtr39f97292016-11-16 22:57:50 -0800590// TODO(brandtr): Move these FlexFEC tests when we have created
591// FlexfecSendStream.
592class FlexfecObserver : public test::EndToEndTest {
593 public:
594 FlexfecObserver(bool header_extensions_enabled,
595 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800596 const std::string& codec,
597 VideoEncoder* encoder)
brandtr39f97292016-11-16 22:57:50 -0800598 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800599 encoder_(encoder),
brandtr39f97292016-11-16 22:57:50 -0800600 payload_name_(codec),
601 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800602 sent_media_(false),
603 sent_flexfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800604 header_extensions_enabled_(header_extensions_enabled) {}
brandtr39f97292016-11-16 22:57:50 -0800605
606 size_t GetNumFlexfecStreams() const override { return 1; }
607
608 private:
609 Action OnSendRtp(const uint8_t* packet, size_t length) override {
610 RTPHeader header;
611 EXPECT_TRUE(parser_->Parse(packet, length, &header));
612
brandtr39f97292016-11-16 22:57:50 -0800613 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
614 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
615 sent_flexfec_ = true;
616 } else {
617 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
618 header.payloadType);
619 EXPECT_EQ(VideoSendStreamTest::kVideoSendSsrcs[0], header.ssrc);
620 sent_media_ = true;
621 }
622
623 if (header_extensions_enabled_) {
624 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
625 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
626 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
627 }
628
brandtr0c5a1542016-11-23 04:42:26 -0800629 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800630 observation_complete_.Set();
631 }
632
633 return SEND_PACKET;
634 }
635
636 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
637 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
638 // Therefore we need some network delay.
639 const int kNetworkDelayMs = 100;
640 FakeNetworkPipe::Config config;
brandtrd654a9b2016-12-05 05:38:19 -0800641 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800642 config.queue_delay_ms = kNetworkDelayMs;
minyue20c84cc2017-04-10 16:57:57 -0700643 return new test::PacketTransport(
644 sender_call, this, test::PacketTransport::kSender,
645 VideoSendStreamTest::payload_type_map_, config);
brandtr39f97292016-11-16 22:57:50 -0800646 }
647
648 void ModifyVideoConfigs(
649 VideoSendStream::Config* send_config,
650 std::vector<VideoReceiveStream::Config>* receive_configs,
651 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800652 if (use_nack_) {
653 send_config->rtp.nack.rtp_history_ms =
654 (*receive_configs)[0].rtp.nack.rtp_history_ms =
655 VideoSendStreamTest::kNackRtpHistoryMs;
656 }
brandtr696c9c62016-12-19 05:47:28 -0800657 send_config->encoder_settings.encoder = encoder_;
brandtr39f97292016-11-16 22:57:50 -0800658 send_config->encoder_settings.payload_name = payload_name_;
659 if (header_extensions_enabled_) {
660 send_config->rtp.extensions.push_back(RtpExtension(
661 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
662 send_config->rtp.extensions.push_back(RtpExtension(
663 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800664 } else {
665 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800666 }
667 }
668
669 void PerformTest() override {
670 EXPECT_TRUE(Wait())
671 << "Timed out waiting for FlexFEC and/or media packets.";
672 }
673
brandtr696c9c62016-12-19 05:47:28 -0800674 VideoEncoder* const encoder_;
675 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800676 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800677 bool sent_media_;
678 bool sent_flexfec_;
679 bool header_extensions_enabled_;
680};
681
brandtrd654a9b2016-12-05 05:38:19 -0800682TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800683 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
684 FlexfecObserver test(false, false, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800685 RunBaseTest(&test);
686}
687
688TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800689 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
690 FlexfecObserver test(false, true, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800691 RunBaseTest(&test);
692}
693
brandtr39f97292016-11-16 22:57:50 -0800694TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800695 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
696 FlexfecObserver test(true, false, "VP8", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800697 RunBaseTest(&test);
698}
699
brandtr39f97292016-11-16 22:57:50 -0800700#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800701TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800702 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
703 FlexfecObserver test(false, false, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800704 RunBaseTest(&test);
705}
706
brandtrd654a9b2016-12-05 05:38:19 -0800707TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800708 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
709 FlexfecObserver test(false, true, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800710 RunBaseTest(&test);
711}
712#endif // defined(RTC_DISABLE_VP9)
713
brandtrd654a9b2016-12-05 05:38:19 -0800714TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
brandtr696c9c62016-12-19 05:47:28 -0800715 std::unique_ptr<VideoEncoder> encoder(
716 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
717 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800718 RunBaseTest(&test);
719}
720
brandtrd654a9b2016-12-05 05:38:19 -0800721TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
brandtr696c9c62016-12-19 05:47:28 -0800722 std::unique_ptr<VideoEncoder> encoder(
723 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
724 FlexfecObserver test(false, true, "H264", encoder.get());
725 RunBaseTest(&test);
726}
727
brandtre78d2662017-01-16 05:57:16 -0800728TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800729 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800730 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800731 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800732 RunBaseTest(&test);
733}
734
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000735void VideoSendStreamTest::TestNackRetransmission(
736 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000737 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000738 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000739 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000740 explicit NackObserver(uint32_t retransmit_ssrc,
741 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000742 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000743 send_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000744 retransmit_ssrc_(retransmit_ssrc),
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000745 retransmit_payload_type_(retransmit_payload_type),
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000746 nacked_sequence_number_(-1) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000747 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000748
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000749 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000750 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000751 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000752 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000753
754 // Nack second packet after receiving the third one.
755 if (++send_count_ == 3) {
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000756 uint16_t nack_sequence_number = header.sequenceNumber - 1;
757 nacked_sequence_number_ = nack_sequence_number;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000758 NullReceiveStatistics null_stats;
Peter Boströmac547a62015-09-17 23:03:57 +0200759 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), &null_stats,
terelius429c3452016-01-21 05:42:04 -0800760 nullptr, nullptr, transport_adapter_.get());
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000761
pbosda903ea2015-10-02 02:36:56 -0700762 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100763 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000764
765 RTCPSender::FeedbackState feedback_state;
766
767 EXPECT_EQ(0,
768 rtcp_sender.SendRTCP(
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000769 feedback_state, kRtcpNack, 1, &nack_sequence_number));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000770 }
771
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000772 uint16_t sequence_number = header.sequenceNumber;
773
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000774 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100775 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
776 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000777 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000778 const uint8_t* rtx_header = packet + header.headerLength;
779 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
780 }
781
782 if (sequence_number == nacked_sequence_number_) {
783 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000784 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
Peter Boström5811a392015-12-10 13:02:50 +0100785 observation_complete_.Set();
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000786 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000787
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000788 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000789 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000790
stefanff483612015-12-21 03:14:00 -0800791 void ModifyVideoConfigs(
792 VideoSendStream::Config* send_config,
793 std::vector<VideoReceiveStream::Config>* receive_configs,
794 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700795 transport_adapter_.reset(
796 new internal::TransportAdapter(send_config->send_transport));
797 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000798 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000799 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100800 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000801 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
802 }
803
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000804 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100805 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000806 }
807
kwiberg27f982b2016-03-01 11:52:33 -0800808 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000809 int send_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000810 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000811 uint8_t retransmit_payload_type_;
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000812 int nacked_sequence_number_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000813 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000814
stefane74eef12016-01-08 06:47:13 -0800815 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000816}
817
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000818TEST_F(VideoSendStreamTest, RetransmitsNack) {
819 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100820 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000821}
822
823TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
824 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000825 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000826}
827
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000828void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
829 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000830 // Use a fake encoder to output a frame of every size in the range [90, 290],
831 // for each size making sure that the exact number of payload bytes received
832 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000833 static const size_t kMaxPacketSize = 128;
834 static const size_t start = 90;
835 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000836
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000837 // Observer that verifies that the expected number of packets and bytes
838 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000839 class FrameFragmentationTest : public test::SendTest,
840 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000841 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000842 FrameFragmentationTest(size_t max_packet_size,
843 size_t start_size,
844 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000845 bool test_generic_packetization,
846 bool use_fec)
847 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000848 encoder_(stop),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000849 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000850 stop_size_(stop_size),
851 test_generic_packetization_(test_generic_packetization),
852 use_fec_(use_fec),
853 packet_count_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000854 accumulated_size_(0),
855 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000856 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000857 current_size_rtp_(start_size),
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000858 current_size_frame_(static_cast<int32_t>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000859 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000860 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700861 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000862 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000863
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000864 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000865 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000866 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000867 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000868 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000869
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000870 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000871
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000872 if (use_fec_) {
873 uint8_t payload_type = packet[header.headerLength];
874 bool is_fec = header.payloadType == kRedPayloadType &&
875 payload_type == kUlpfecPayloadType;
876 if (is_fec) {
877 fec_packet_received_ = true;
878 return SEND_PACKET;
879 }
880 }
881
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000882 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000883
884 if (use_fec_)
885 TriggerLossReport(header);
886
887 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200888 size_t overhead = header.headerLength + header.paddingLength;
889 // Only remove payload header and RED header if the packet actually
890 // contains payload.
891 if (length > overhead) {
892 overhead += (1 /* Generic header */);
893 if (use_fec_)
894 overhead += 1; // RED for FEC header.
895 }
896 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000897 accumulated_payload_ += length - overhead;
898 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000899
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000900 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000901 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000902 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
903 // With FEC enabled, frame size is incremented asynchronously, so
904 // "old" frames one byte too small may arrive. Accept, but don't
905 // increase expected frame size.
906 accumulated_size_ = 0;
907 accumulated_payload_ = 0;
908 return SEND_PACKET;
909 }
910
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000911 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000912 if (test_generic_packetization_) {
913 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
914 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000915
916 // Last packet of frame; reset counters.
917 accumulated_size_ = 0;
918 accumulated_payload_ = 0;
919 if (current_size_rtp_ == stop_size_) {
920 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +0100921 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000922 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000923 // Increase next expected frame size. If testing with FEC, make sure
924 // a FEC packet has been received for this frame size before
925 // proceeding, to make sure that redundancy packets don't exceed
926 // size limit.
927 if (!use_fec_) {
928 ++current_size_rtp_;
929 } else if (fec_packet_received_) {
930 fec_packet_received_ = false;
931 ++current_size_rtp_;
932 ++current_size_frame_;
933 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000934 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000935 }
936
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000937 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000938 }
939
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000940 void TriggerLossReport(const RTPHeader& header) {
941 // Send lossy receive reports to trigger FEC enabling.
sprang317005a2017-06-08 07:12:17 -0700942 if (packet_count_++ % 2 != 0) {
943 // Receive statistics reporting having lost 50% of the packets.
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000944 FakeReceiveStatistics lossy_receive_stats(
sprang317005a2017-06-08 07:12:17 -0700945 kVideoSendSsrcs[0], header.sequenceNumber, packet_count_ / 2, 127);
Peter Boströmac547a62015-09-17 23:03:57 +0200946 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -0800947 &lossy_receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -0700948 transport_adapter_.get());
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000949
pbosda903ea2015-10-02 02:36:56 -0700950 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100951 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000952
953 RTCPSender::FeedbackState feedback_state;
954
955 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
956 }
957 }
958
nisseef8b61e2016-04-29 06:09:15 -0700959 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000960 // Increase frame size for next encoded frame, in the context of the
961 // encoder thread.
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000962 if (!use_fec_ &&
963 current_size_frame_.Value() < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000964 ++current_size_frame_;
965 }
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000966 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_.Value()));
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000967 }
968
Stefan Holmere5904162015-03-26 11:11:06 +0100969 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -0700970 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +0100971 const int kMinBitrateBps = 30000;
972 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
973 return config;
974 }
975
stefanff483612015-12-21 03:14:00 -0800976 void ModifyVideoConfigs(
977 VideoSendStream::Config* send_config,
978 std::vector<VideoReceiveStream::Config>* receive_configs,
979 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700980 transport_adapter_.reset(
981 new internal::TransportAdapter(send_config->send_transport));
982 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000983 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -0700984 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
985 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000986 }
987
988 if (!test_generic_packetization_)
989 send_config->encoder_settings.payload_name = "VP8";
990
991 send_config->encoder_settings.encoder = &encoder_;
992 send_config->rtp.max_packet_size = kMaxPacketSize;
993 send_config->post_encode_callback = this;
994
Erik Språng95261872015-04-10 11:58:49 +0200995 // Make sure there is at least one extension header, to make the RTP
996 // header larger than the base length of 12 bytes.
997 EXPECT_FALSE(send_config->rtp.extensions.empty());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000998 }
999
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001000 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001001 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001002 }
1003
kwiberg27f982b2016-03-01 11:52:33 -08001004 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001005 test::ConfigurableFrameSizeEncoder encoder_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001006
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001007 const size_t max_packet_size_;
1008 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001009 const bool test_generic_packetization_;
1010 const bool use_fec_;
1011
1012 uint32_t packet_count_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001013 size_t accumulated_size_;
1014 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001015 bool fec_packet_received_;
1016
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001017 size_t current_size_rtp_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001018 Atomic32 current_size_frame_;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001019 };
1020
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001021 // Don't auto increment if FEC is used; continue sending frame size until
1022 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001023 FrameFragmentationTest test(
1024 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +00001025
stefane74eef12016-01-08 06:47:13 -08001026 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +00001027}
1028
sprang@webrtc.org346094c2014-02-18 08:40:33 +00001029// TODO(sprang): Is there any way of speeding up these tests?
1030TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
1031 TestPacketFragmentationSize(kGeneric, false);
1032}
1033
1034TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
1035 TestPacketFragmentationSize(kGeneric, true);
1036}
1037
1038TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
1039 TestPacketFragmentationSize(kVP8, false);
1040}
1041
1042TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
1043 TestPacketFragmentationSize(kVP8, true);
1044}
1045
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001046// The test will go through a number of phases.
1047// 1. Start sending packets.
1048// 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 +00001049// suspend the stream.
1050// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001051// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001052// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001053// When the stream is detected again, and the stats show that the stream
1054// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001055TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1056 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001057
nissed30a1112016-04-18 05:15:22 -07001058 class RembObserver : public test::SendTest,
1059 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001060 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001061 RembObserver()
1062 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001063 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001064 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001065 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001066 rtp_count_(0),
1067 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001068 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001069 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001070 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001071
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001072 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001073 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001074 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001075 ++rtp_count_;
1076 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001077 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001078 last_sequence_number_ = header.sequenceNumber;
1079
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001080 if (test_state_ == kBeforeSuspend) {
1081 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001082 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001083 test_state_ = kDuringSuspend;
1084 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001085 if (header.paddingLength == 0) {
1086 // Received non-padding packet during suspension period. Reset the
1087 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001088 suspended_frame_count_ = 0;
1089 }
stefanf116bd02015-10-27 08:29:42 -07001090 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001091 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001092 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001093 // Non-padding packet observed. Test is almost complete. Will just
1094 // have to wait for the stats to change.
1095 test_state_ = kWaitingForStats;
1096 }
stefanf116bd02015-10-27 08:29:42 -07001097 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001098 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001099 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001100 if (stats.suspended == false) {
1101 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001102 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001103 }
stefanf116bd02015-10-27 08:29:42 -07001104 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001105 }
1106
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001107 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001108 }
1109
perkj26091b12016-09-01 01:17:40 -07001110 // This method implements the rtc::VideoSinkInterface. This is called when
1111 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001112 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001113 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001114 if (test_state_ == kDuringSuspend &&
1115 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001116 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001117 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001118 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001119 test_state_ = kWaitingForPacket;
1120 }
1121 }
1122
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001123 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001124 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001125 low_remb_bps_ = value;
1126 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001127
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001128 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001129 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001130 high_remb_bps_ = value;
1131 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001132
stefanff483612015-12-21 03:14:00 -08001133 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001134 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001135 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001136 stream_ = send_stream;
1137 }
1138
stefanff483612015-12-21 03:14:00 -08001139 void ModifyVideoConfigs(
1140 VideoSendStream::Config* send_config,
1141 std::vector<VideoReceiveStream::Config>* receive_configs,
1142 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001143 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001144 transport_adapter_.reset(
1145 new internal::TransportAdapter(send_config->send_transport));
1146 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001147 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001148 send_config->pre_encode_callback = this;
1149 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001150 int min_bitrate_bps =
1151 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001152 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001153 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001154 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001155 min_bitrate_bps + threshold_window + 5000);
1156 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1157 }
1158
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001159 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001160 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001161 }
1162
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001163 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001164 kBeforeSuspend,
1165 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001166 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001167 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001168 };
1169
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001170 virtual void SendRtcpFeedback(int remb_value)
1171 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001172 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1173 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001174 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -07001175 transport_adapter_.get());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001176
pbosda903ea2015-10-02 02:36:56 -07001177 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001178 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001179 if (remb_value > 0) {
1180 rtcp_sender.SetREMBStatus(true);
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001181 rtcp_sender.SetREMBData(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001182 }
1183 RTCPSender::FeedbackState feedback_state;
1184 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1185 }
1186
kwiberg27f982b2016-03-01 11:52:33 -08001187 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001188 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001189 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001190
Peter Boströmf2f82832015-05-01 13:00:41 +02001191 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001192 TestState test_state_ GUARDED_BY(crit_);
1193 int rtp_count_ GUARDED_BY(crit_);
1194 int last_sequence_number_ GUARDED_BY(crit_);
1195 int suspended_frame_count_ GUARDED_BY(crit_);
1196 int low_remb_bps_ GUARDED_BY(crit_);
1197 int high_remb_bps_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001198 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001199
stefane74eef12016-01-08 06:47:13 -08001200 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001201}
1202
perkj71ee44c2016-06-15 00:47:53 -07001203// This test that padding stops being send after a while if the Camera stops
1204// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001205TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001206 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001207 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001208 NoPaddingWhenVideoIsMuted()
1209 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001210 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001211 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001212 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +00001213 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001214
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001215 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001216 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001217 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001218 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001219
1220 RTPHeader header;
1221 parser_->Parse(packet, length, &header);
1222 const bool only_padding =
1223 header.headerLength + header.paddingLength == length;
1224
1225 if (test_state_ == kBeforeStopCapture) {
1226 capturer_->Stop();
1227 test_state_ = kWaitingForPadding;
1228 } else if (test_state_ == kWaitingForPadding && only_padding) {
1229 test_state_ = kWaitingForNoPackets;
1230 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1231 only_padding) {
1232 observation_complete_.Set();
1233 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001234 return SEND_PACKET;
1235 }
1236
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001237 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001238 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001239 const int kNoPacketsThresholdMs = 2000;
1240 if (test_state_ == kWaitingForNoPackets &&
1241 (last_packet_time_ms_ > 0 &&
1242 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1243 kNoPacketsThresholdMs)) {
1244 capturer_->Start();
1245 test_state_ = kWaitingForPaddingAfterCameraRestart;
1246 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001247 return SEND_PACKET;
1248 }
1249
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001250 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001251
nisseef8b61e2016-04-29 06:09:15 -07001252 void OnFrameGeneratorCapturerCreated(
1253 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001254 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001255 capturer_ = frame_generator_capturer;
1256 }
1257
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001258 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001259 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001260 << "Timed out while waiting for RTP packets to stop being sent.";
1261 }
1262
perkj71ee44c2016-06-15 00:47:53 -07001263 enum TestState {
1264 kBeforeStopCapture,
1265 kWaitingForPadding,
1266 kWaitingForNoPackets,
1267 kWaitingForPaddingAfterCameraRestart
1268 };
1269
1270 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001271 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001272 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001273 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001274 int64_t last_packet_time_ms_ GUARDED_BY(crit_);
1275 test::FrameGeneratorCapturer* capturer_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001276 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001277
stefane74eef12016-01-08 06:47:13 -08001278 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001279}
1280
isheriffcc5903e2016-10-04 08:29:38 -07001281TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1282 const int kCapacityKbps = 10000; // 10 Mbps
1283 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1284 public:
1285 PaddingIsPrimarilyRetransmissions()
1286 : EndToEndTest(kDefaultTimeoutMs),
1287 clock_(Clock::GetRealTimeClock()),
1288 padding_length_(0),
1289 total_length_(0),
1290 call_(nullptr) {}
1291
1292 private:
1293 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1294 call_ = sender_call;
1295 }
1296
1297 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1298 rtc::CritScope lock(&crit_);
1299
1300 RTPHeader header;
1301 parser_->Parse(packet, length, &header);
1302 padding_length_ += header.paddingLength;
1303 total_length_ += length;
1304 return SEND_PACKET;
1305 }
1306
1307 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
1308 const int kNetworkDelayMs = 50;
1309 FakeNetworkPipe::Config config;
1310 config.loss_percent = 10;
1311 config.link_capacity_kbps = kCapacityKbps;
1312 config.queue_delay_ms = kNetworkDelayMs;
1313 return new test::PacketTransport(sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -07001314 test::PacketTransport::kSender,
minyue20c84cc2017-04-10 16:57:57 -07001315 payload_type_map_, config);
isheriffcc5903e2016-10-04 08:29:38 -07001316 }
1317
1318 void ModifyVideoConfigs(
1319 VideoSendStream::Config* send_config,
1320 std::vector<VideoReceiveStream::Config>* receive_configs,
1321 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001322 // Turn on RTX.
1323 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1324 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001325 }
1326
1327 void PerformTest() override {
1328 // TODO(isheriff): Some platforms do not ramp up as expected to full
1329 // capacity due to packet scheduling delays. Fix that before getting
1330 // rid of this.
1331 SleepMs(5000);
1332 {
1333 rtc::CritScope lock(&crit_);
1334 // Expect padding to be a small percentage of total bytes sent.
1335 EXPECT_LT(padding_length_, .1 * total_length_);
1336 }
1337 }
1338
1339 rtc::CriticalSection crit_;
1340 Clock* const clock_;
1341 size_t padding_length_ GUARDED_BY(crit_);
1342 size_t total_length_ GUARDED_BY(crit_);
1343 Call* call_;
1344 } test;
1345
1346 RunBaseTest(&test);
1347}
1348
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001349// This test first observes "high" bitrate use at which point it sends a REMB to
1350// indicate that it should be lowered significantly. The test then observes that
1351// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1352// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001353//
1354// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1355// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001356TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1357 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001358 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001359 static const int kRembBitrateBps = 80000;
1360 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001361 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001362 public:
1363 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001364 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001365 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1366 stream_(nullptr),
1367 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001368
1369 private:
nisseef8b61e2016-04-29 06:09:15 -07001370 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001371 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001372 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001373
1374 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001375 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001376 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001377 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001378 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001379 if (!stats.substreams.empty()) {
1380 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001381 int total_bitrate_bps =
1382 stats.substreams.begin()->second.total_bitrate_bps;
1383 test::PrintResult("bitrate_stats_",
1384 "min_transmit_bitrate_low_remb",
1385 "bitrate_bps",
1386 static_cast<size_t>(total_bitrate_bps),
1387 "bps",
1388 false);
1389 if (total_bitrate_bps > kHighBitrateBps) {
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001390 rtp_rtcp_->SetREMBData(kRembBitrateBps,
1391 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001392 rtp_rtcp_->Process();
1393 bitrate_capped_ = true;
1394 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001395 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001396 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001397 }
1398 }
stefanf116bd02015-10-27 08:29:42 -07001399 // Packets don't have to be delivered since the test is the receiver.
1400 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001401 }
1402
stefanff483612015-12-21 03:14:00 -08001403 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001404 VideoSendStream* send_stream,
1405 const std::vector<VideoReceiveStream*>& receive_streams) override {
1406 stream_ = send_stream;
1407 RtpRtcp::Configuration config;
1408 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001409 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001410 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
1411 rtp_rtcp_->SetREMBStatus(true);
1412 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001413 }
1414
stefanff483612015-12-21 03:14:00 -08001415 void ModifyVideoConfigs(
1416 VideoSendStream::Config* send_config,
1417 std::vector<VideoReceiveStream::Config>* receive_configs,
1418 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001419 feedback_transport_.reset(
1420 new internal::TransportAdapter(send_config->send_transport));
1421 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001422 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001423 }
1424
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001425 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001426 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001427 << "Timeout while waiting for low bitrate stats after REMB.";
1428 }
1429
kwiberg27f982b2016-03-01 11:52:33 -08001430 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1431 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001432 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001433 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001434 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001435 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001436
stefane74eef12016-01-08 06:47:13 -08001437 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001438}
1439
Stefan Holmer280de9e2016-09-30 10:06:51 +02001440TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1441 static const int kStartBitrateBps = 300000;
1442 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001443 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001444 class ChangingNetworkRouteTest : public test::EndToEndTest {
1445 public:
Stefan Holmerbe402962016-07-08 16:16:41 +02001446 ChangingNetworkRouteTest()
Stefan Holmer280de9e2016-09-30 10:06:51 +02001447 : EndToEndTest(test::CallTest::kDefaultTimeoutMs), call_(nullptr) {
1448 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1449 kRtpExtensionTransportSequenceNumber, kExtensionId));
1450 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001451
1452 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1453 call_ = sender_call;
1454 }
1455
Stefan Holmer280de9e2016-09-30 10:06:51 +02001456 void ModifyVideoConfigs(
1457 VideoSendStream::Config* send_config,
1458 std::vector<VideoReceiveStream::Config>* receive_configs,
1459 VideoEncoderConfig* encoder_config) override {
1460 send_config->rtp.extensions.clear();
1461 send_config->rtp.extensions.push_back(RtpExtension(
1462 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1463 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1464 (*receive_configs)[0].rtp.transport_cc = true;
1465 }
1466
1467 void ModifyAudioConfigs(
1468 AudioSendStream::Config* send_config,
1469 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1470 send_config->rtp.extensions.clear();
1471 send_config->rtp.extensions.push_back(RtpExtension(
1472 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1473 (*receive_configs)[0].rtp.extensions.clear();
1474 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1475 (*receive_configs)[0].rtp.transport_cc = true;
1476 }
1477
Stefan Holmerbe402962016-07-08 16:16:41 +02001478 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1479 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1480 observation_complete_.Set();
1481 }
1482
1483 return SEND_PACKET;
1484 }
1485
1486 void PerformTest() override {
1487 rtc::NetworkRoute new_route(true, 10, 20, -1);
1488 call_->OnNetworkRouteChanged("transport", new_route);
1489 Call::Config::BitrateConfig bitrate_config;
1490 bitrate_config.start_bitrate_bps = kStartBitrateBps;
1491 call_->SetBitrateConfig(bitrate_config);
1492 EXPECT_TRUE(Wait())
1493 << "Timed out while waiting for start bitrate to be exceeded.";
1494
1495 bitrate_config.start_bitrate_bps = -1;
1496 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
1497 call_->SetBitrateConfig(bitrate_config);
1498 // TODO(holmer): We should set the last sent packet id here and verify
1499 // that we correctly ignore any packet loss reported prior to that id.
1500 ++new_route.local_network_id;
1501 call_->OnNetworkRouteChanged("transport", new_route);
stefan01bbc3c2016-10-25 04:19:48 -07001502 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
Stefan Holmerbe402962016-07-08 16:16:41 +02001503 }
1504
1505 private:
1506 Call* call_;
1507 } test;
1508
1509 RunBaseTest(&test);
1510}
1511
michaelt79e05882016-11-08 02:50:09 -08001512TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
1513 class ChangingTransportOverheadTest : public test::EndToEndTest {
1514 public:
1515 ChangingTransportOverheadTest()
1516 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1517 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001518 packets_sent_(0),
1519 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001520
1521 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1522 call_ = sender_call;
1523 }
1524
1525 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001526 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001527 rtc::CritScope cs(&lock_);
michaelt79e05882016-11-08 02:50:09 -08001528 if (++packets_sent_ < 100)
1529 return SEND_PACKET;
1530 observation_complete_.Set();
1531 return SEND_PACKET;
1532 }
1533
michaelta3328772016-11-29 09:25:03 -08001534 void ModifyVideoConfigs(
1535 VideoSendStream::Config* send_config,
1536 std::vector<VideoReceiveStream::Config>* receive_configs,
1537 VideoEncoderConfig* encoder_config) override {
1538 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1539 }
1540
michaelt79e05882016-11-08 02:50:09 -08001541 void PerformTest() override {
michaelta3328772016-11-29 09:25:03 -08001542 transport_overhead_ = 100;
michaelt79e05882016-11-08 02:50:09 -08001543 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1544 transport_overhead_);
1545 EXPECT_TRUE(Wait());
sprang21253fc2017-02-27 03:35:47 -08001546 {
1547 rtc::CritScope cs(&lock_);
1548 packets_sent_ = 0;
1549 }
michaelta3328772016-11-29 09:25:03 -08001550 transport_overhead_ = 500;
michaelt79e05882016-11-08 02:50:09 -08001551 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1552 transport_overhead_);
1553 EXPECT_TRUE(Wait());
1554 }
1555
1556 private:
1557 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001558 rtc::CriticalSection lock_;
1559 int packets_sent_ GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001560 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001561 const size_t kMaxRtpPacketSize = 1000;
michaelt79e05882016-11-08 02:50:09 -08001562 } test;
1563
1564 RunBaseTest(&test);
1565}
1566
sprangf24a0642017-02-28 13:23:26 -08001567// Test class takes takes as argument a switch selecting if type switch should
1568// occur and a function pointer to reset the send stream. This is necessary
1569// since you cannot change the content type of a VideoSendStream, you need to
1570// recreate it. Stopping and recreating the stream can only be done on the main
1571// thread and in the context of VideoSendStreamTest (not BaseTest).
1572template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001573class MaxPaddingSetTest : public test::SendTest {
1574 public:
1575 static const uint32_t kMinTransmitBitrateBps = 400000;
1576 static const uint32_t kActualEncodeBitrateBps = 40000;
1577 static const uint32_t kMinPacketsToSend = 50;
1578
sprangf24a0642017-02-28 13:23:26 -08001579 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001580 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001581 content_switch_event_(false, false),
sprang9c0b5512016-07-06 00:54:28 -07001582 call_(nullptr),
1583 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001584 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001585 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001586 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001587 stream_resetter_(stream_reset_fun) {
1588 RTC_DCHECK(stream_resetter_);
1589 }
sprang9c0b5512016-07-06 00:54:28 -07001590
1591 void OnVideoStreamsCreated(
1592 VideoSendStream* send_stream,
1593 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001594 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001595 send_stream_ = send_stream;
1596 }
1597
1598 void ModifyVideoConfigs(
1599 VideoSendStream::Config* send_config,
1600 std::vector<VideoReceiveStream::Config>* receive_configs,
1601 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001602 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001603 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001604 encoder_config->min_transmit_bitrate_bps = 0;
1605 encoder_config->content_type =
1606 VideoEncoderConfig::ContentType::kRealtimeVideo;
1607 } else {
1608 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1609 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1610 }
sprangf24a0642017-02-28 13:23:26 -08001611 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001612 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001613 }
1614
1615 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1616 call_ = sender_call;
1617 }
1618
1619 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1620 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001621 if (running_without_padding_)
1622 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1623
1624 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1625 // we have reliable data.
1626 if (++packets_sent_ < kMinPacketsToSend)
1627 return SEND_PACKET;
1628
1629 if (running_without_padding_) {
1630 // We've sent kMinPacketsToSend packets with default configuration, switch
1631 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001632 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001633 packets_sent_ = 0;
1634 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1635 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001636 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001637 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001638 return SEND_PACKET;
1639 }
1640
1641 // Make sure the pacer has been configured with a min transmit bitrate.
1642 if (call_->GetStats().max_padding_bitrate_bps > 0)
1643 observation_complete_.Set();
1644
1645 return SEND_PACKET;
1646 }
1647
1648 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001649 if (RunningWithoutPadding()) {
1650 ASSERT_TRUE(
1651 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001652 (*stream_resetter_)(send_stream_config_, encoder_config_);
1653 }
1654
sprang9c0b5512016-07-06 00:54:28 -07001655 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1656 }
1657
1658 private:
sprangf24a0642017-02-28 13:23:26 -08001659 bool RunningWithoutPadding() const {
1660 rtc::CritScope lock(&crit_);
1661 return running_without_padding_;
1662 }
1663
sprang9c0b5512016-07-06 00:54:28 -07001664 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001665 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001666 Call* call_;
sprangf24a0642017-02-28 13:23:26 -08001667 VideoSendStream* send_stream_ GUARDED_BY(crit_);
1668 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001669 VideoEncoderConfig encoder_config_;
1670 uint32_t packets_sent_ GUARDED_BY(crit_);
1671 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001672 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001673};
1674
1675TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001676 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1677 const VideoEncoderConfig& encoder_config) {};
1678 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001679 RunBaseTest(&test);
1680}
1681
1682TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001683 // Function for removing and recreating the send stream with a new config.
1684 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1685 const VideoEncoderConfig& encoder_config) {
1686 Stop();
1687 sender_call_->DestroyVideoSendStream(video_send_stream_);
1688 video_send_config_ = send_stream_config.Copy();
1689 video_encoder_config_ = encoder_config.Copy();
1690 video_send_stream_ = sender_call_->CreateVideoSendStream(
1691 video_send_config_.Copy(), video_encoder_config_.Copy());
1692 video_send_stream_->SetSource(
1693 frame_generator_capturer_.get(),
1694 VideoSendStream::DegradationPreference::kMaintainResolution);
1695 Start();
1696 };
1697 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001698 RunBaseTest(&test);
1699}
1700
perkjfa10b552016-10-02 23:45:26 -07001701// This test verifies that new frame sizes reconfigures encoders even though not
1702// (yet) sending. The purpose of this is to permit encoding as quickly as
1703// possible once we start sending. Likely the frames being input are from the
1704// same source that will be sent later, which just means that we're ready
1705// earlier.
1706TEST_F(VideoSendStreamTest,
1707 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1708 class EncoderObserver : public test::FakeEncoder {
1709 public:
1710 EncoderObserver()
1711 : FakeEncoder(Clock::GetRealTimeClock()),
1712 init_encode_called_(false, false),
1713 number_of_initializations_(0),
1714 last_initialized_frame_width_(0),
1715 last_initialized_frame_height_(0) {}
1716
1717 void WaitForResolution(int width, int height) {
1718 {
1719 rtc::CritScope lock(&crit_);
1720 if (last_initialized_frame_width_ == width &&
1721 last_initialized_frame_height_ == height) {
1722 return;
1723 }
1724 }
Erik Språng08127a92016-11-16 16:41:30 +01001725 EXPECT_TRUE(
1726 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001727 {
1728 rtc::CritScope lock(&crit_);
1729 EXPECT_EQ(width, last_initialized_frame_width_);
1730 EXPECT_EQ(height, last_initialized_frame_height_);
1731 }
1732 }
1733
1734 private:
1735 int32_t InitEncode(const VideoCodec* config,
1736 int32_t number_of_cores,
1737 size_t max_payload_size) override {
1738 rtc::CritScope lock(&crit_);
1739 last_initialized_frame_width_ = config->width;
1740 last_initialized_frame_height_ = config->height;
1741 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001742 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001743 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1744 }
1745
1746 int32_t Encode(const VideoFrame& input_image,
1747 const CodecSpecificInfo* codec_specific_info,
1748 const std::vector<FrameType>* frame_types) override {
1749 ADD_FAILURE()
1750 << "Unexpected Encode call since the send stream is not started";
1751 return 0;
1752 }
1753
1754 rtc::CriticalSection crit_;
1755 rtc::Event init_encode_called_;
1756 size_t number_of_initializations_ GUARDED_BY(&crit_);
1757 int last_initialized_frame_width_ GUARDED_BY(&crit_);
1758 int last_initialized_frame_height_ GUARDED_BY(&crit_);
1759 };
1760
philipel4fb651d2017-04-10 03:54:05 -07001761 CreateSenderCall(Call::Config(event_log_.get()));
perkjfa10b552016-10-02 23:45:26 -07001762 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001763 CreateSendConfig(1, 0, 0, &transport);
perkjfa10b552016-10-02 23:45:26 -07001764 EncoderObserver encoder;
1765 video_send_config_.encoder_settings.encoder = &encoder;
1766 CreateVideoStreams();
1767 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1768 kDefaultHeight);
1769 frame_generator_capturer_->Start();
1770
1771 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
1772 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1773 kDefaultHeight * 2);
1774 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
1775 DestroyStreams();
1776}
1777
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001778TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1779 class StartBitrateObserver : public test::FakeEncoder {
1780 public:
1781 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001782 : FakeEncoder(Clock::GetRealTimeClock()),
1783 start_bitrate_changed_(false, false),
1784 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001785 int32_t InitEncode(const VideoCodec* config,
1786 int32_t number_of_cores,
1787 size_t max_payload_size) override {
1788 rtc::CritScope lock(&crit_);
1789 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001790 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001791 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1792 }
1793
1794 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1795 rtc::CritScope lock(&crit_);
1796 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001797 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001798 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1799 }
1800
1801 int GetStartBitrateKbps() const {
1802 rtc::CritScope lock(&crit_);
1803 return start_bitrate_kbps_;
1804 }
1805
pbos14fe7082016-04-20 06:35:56 -07001806 bool WaitForStartBitrate() {
1807 return start_bitrate_changed_.Wait(
1808 VideoSendStreamTest::kDefaultTimeoutMs);
1809 }
1810
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001811 private:
pbos5ad935c2016-01-25 03:52:44 -08001812 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001813 rtc::Event start_bitrate_changed_;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001814 int start_bitrate_kbps_ GUARDED_BY(crit_);
1815 };
1816
philipel4fb651d2017-04-10 03:54:05 -07001817 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001818
solenberg4fbae2b2015-08-28 04:07:10 -07001819 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001820 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001821
1822 Call::Config::BitrateConfig bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07001823 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001824 sender_call_->SetBitrateConfig(bitrate_config);
1825
1826 StartBitrateObserver encoder;
stefanff483612015-12-21 03:14:00 -08001827 video_send_config_.encoder_settings.encoder = &encoder;
perkjfa10b552016-10-02 23:45:26 -07001828 // Since this test does not use a capturer, set |internal_source| = true.
1829 // Encoder configuration is otherwise updated on the next video frame.
1830 video_send_config_.encoder_settings.internal_source = true;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001831
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001832 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001833
pbos14fe7082016-04-20 06:35:56 -07001834 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07001835 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001836 encoder.GetStartBitrateKbps());
1837
perkjfa10b552016-10-02 23:45:26 -07001838 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07001839 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001840
1841 // New bitrate should be reconfigured above the previous max. As there's no
1842 // network connection this shouldn't be flaky, as no bitrate should've been
1843 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07001844 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001845 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
1846 encoder.GetStartBitrateKbps());
1847
1848 DestroyStreams();
1849}
1850
perkj57c21f92016-06-17 07:27:16 -07001851// This test that if the encoder use an internal source, VideoEncoder::SetRates
1852// will be called with zero bitrate during initialization and that
1853// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
1854// with zero bitrate.
1855TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
1856 class StartStopBitrateObserver : public test::FakeEncoder {
1857 public:
1858 StartStopBitrateObserver()
1859 : FakeEncoder(Clock::GetRealTimeClock()),
1860 encoder_init_(false, false),
Erik Språng08127a92016-11-16 16:41:30 +01001861 bitrate_changed_(false, false) {}
perkj57c21f92016-06-17 07:27:16 -07001862 int32_t InitEncode(const VideoCodec* config,
1863 int32_t number_of_cores,
1864 size_t max_payload_size) override {
1865 rtc::CritScope lock(&crit_);
perkj57c21f92016-06-17 07:27:16 -07001866 encoder_init_.Set();
1867 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1868 }
1869
Erik Språng08127a92016-11-16 16:41:30 +01001870 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
1871 uint32_t framerate) override {
perkj57c21f92016-06-17 07:27:16 -07001872 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01001873 bitrate_kbps_ = rtc::Optional<int>(bitrate.get_sum_kbps());
perkj57c21f92016-06-17 07:27:16 -07001874 bitrate_changed_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01001875 return FakeEncoder::SetRateAllocation(bitrate, framerate);
perkj57c21f92016-06-17 07:27:16 -07001876 }
1877
1878 bool WaitForEncoderInit() {
1879 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1880 }
Erik Språng08127a92016-11-16 16:41:30 +01001881
1882 bool WaitBitrateChanged(bool non_zero) {
1883 do {
1884 rtc::Optional<int> bitrate_kbps;
1885 {
1886 rtc::CritScope lock(&crit_);
1887 bitrate_kbps = bitrate_kbps_;
1888 }
1889 if (!bitrate_kbps)
1890 continue;
1891
1892 if ((non_zero && *bitrate_kbps > 0) ||
1893 (!non_zero && *bitrate_kbps == 0)) {
1894 return true;
1895 }
1896 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
1897 return false;
perkj57c21f92016-06-17 07:27:16 -07001898 }
1899
1900 private:
1901 rtc::CriticalSection crit_;
1902 rtc::Event encoder_init_;
1903 rtc::Event bitrate_changed_;
Erik Språng08127a92016-11-16 16:41:30 +01001904 rtc::Optional<int> bitrate_kbps_ GUARDED_BY(crit_);
perkj57c21f92016-06-17 07:27:16 -07001905 };
1906
philipel4fb651d2017-04-10 03:54:05 -07001907 CreateSenderCall(Call::Config(event_log_.get()));
perkj57c21f92016-06-17 07:27:16 -07001908
1909 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001910 CreateSendConfig(1, 0, 0, &transport);
perkj57c21f92016-06-17 07:27:16 -07001911
Sergey Ulanove2b15012016-11-22 16:08:30 -08001912 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
1913
perkj57c21f92016-06-17 07:27:16 -07001914 StartStopBitrateObserver encoder;
1915 video_send_config_.encoder_settings.encoder = &encoder;
1916 video_send_config_.encoder_settings.internal_source = true;
1917
1918 CreateVideoStreams();
1919
1920 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01001921
perkj57c21f92016-06-17 07:27:16 -07001922 video_send_stream_->Start();
Erik Språng08127a92016-11-16 16:41:30 +01001923 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
1924
perkj57c21f92016-06-17 07:27:16 -07001925 video_send_stream_->Stop();
Erik Språng08127a92016-11-16 16:41:30 +01001926 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
1927
perkj57c21f92016-06-17 07:27:16 -07001928 video_send_stream_->Start();
Erik Språng08127a92016-11-16 16:41:30 +01001929 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07001930
1931 DestroyStreams();
1932}
1933
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001934TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07001935 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001936 public:
Peter Boström5811a392015-12-10 13:02:50 +01001937 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001938
nissed30a1112016-04-18 05:15:22 -07001939 void OnFrame(const VideoFrame& video_frame) override {
1940 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01001941 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001942 }
1943
1944 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01001945 const int kWaitFrameTimeoutMs = 3000;
1946 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001947 << "Timeout while waiting for output frames.";
1948 }
1949
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001950 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001951 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001952 }
1953
1954 private:
1955 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001956 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001957
1958 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01001959 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001960 };
1961
1962 // Initialize send stream.
philipel4fb651d2017-04-10 03:54:05 -07001963 CreateSenderCall(Call::Config(event_log_.get()));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001964
solenberg4fbae2b2015-08-28 04:07:10 -07001965 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001966 CreateSendConfig(1, 0, 0, &transport);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001967 FrameObserver observer;
stefanff483612015-12-21 03:14:00 -08001968 video_send_config_.pre_encode_callback = &observer;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001969 CreateVideoStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001970
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001971 // Prepare five input frames. Send ordinary VideoFrame and texture frames
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001972 // alternatively.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001973 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07001974 int width = 168;
1975 int height = 132;
1976
Peter Boströmeb66e802015-06-05 11:08:03 +02001977 test::FakeNativeHandle* handle1 = new test::FakeNativeHandle();
1978 test::FakeNativeHandle* handle2 = new test::FakeNativeHandle();
1979 test::FakeNativeHandle* handle3 = new test::FakeNativeHandle();
Peter Boström13f61df2016-01-04 22:36:38 +01001980 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001981 handle1, width, height, 1, 1, kVideoRotation_0));
Peter Boström13f61df2016-01-04 22:36:38 +01001982 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001983 handle2, width, height, 2, 2, kVideoRotation_0));
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001984 input_frames.push_back(CreateVideoFrame(width, height, 3));
1985 input_frames.push_back(CreateVideoFrame(width, height, 4));
Peter Boström13f61df2016-01-04 22:36:38 +01001986 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001987 handle3, width, height, 5, 5, kVideoRotation_0));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001988
stefanff483612015-12-21 03:14:00 -08001989 video_send_stream_->Start();
perkja49cbd32016-09-16 07:53:41 -07001990 test::FrameForwarder forwarder;
perkj803d97f2016-11-01 11:45:46 -07001991 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07001992 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001993 for (size_t i = 0; i < input_frames.size(); i++) {
perkja49cbd32016-09-16 07:53:41 -07001994 forwarder.IncomingCapturedFrame(input_frames[i]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001995 // Wait until the output frame is received before sending the next input
1996 // frame. Or the previous input frame may be replaced without delivering.
1997 observer.WaitOutputFrame();
1998 }
stefanff483612015-12-21 03:14:00 -08001999 video_send_stream_->Stop();
perkj803d97f2016-11-01 11:45:46 -07002000 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07002001 nullptr, VideoSendStream::DegradationPreference::kMaintainFramerate);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002002
2003 // Test if the input and output frames are the same. render_time_ms and
2004 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002005 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002006
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002007 DestroyStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002008}
2009
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002010void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
2011 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002012 EXPECT_EQ(frames1.size(), frames2.size());
2013 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07002014 // Compare frame buffers, since we don't care about differing timestamps.
2015 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
2016 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002017}
2018
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002019VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002020 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08002021 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002022 memset(buffer.get(), data, kSizeY);
nissef0a7c5a2016-10-31 05:48:07 -07002023 VideoFrame frame(
2024 I420Buffer::Create(width, height, width, width / 2, width / 2),
2025 kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00002026 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08002027 // Use data as a ms timestamp.
2028 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00002029 return frame;
2030}
2031
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002032TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
2033 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
2034 public:
2035 EncoderStateObserver()
2036 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002037 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002038 initialized_(false),
2039 callback_registered_(false),
2040 num_releases_(0),
2041 released_(false) {}
2042
2043 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002044 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002045 return released_;
2046 }
2047
2048 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002049 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002050 return initialized_ && callback_registered_;
2051 }
2052
2053 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002054 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002055 return num_releases_;
2056 }
2057
2058 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002059 int32_t InitEncode(const VideoCodec* codecSettings,
2060 int32_t numberOfCores,
2061 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002062 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002063 EXPECT_FALSE(initialized_);
2064 initialized_ = true;
2065 released_ = false;
2066 return 0;
2067 }
2068
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002069 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002070 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002071 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002072 EXPECT_TRUE(IsReadyForEncode());
2073
Peter Boström5811a392015-12-10 13:02:50 +01002074 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002075 return 0;
2076 }
2077
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002078 int32_t RegisterEncodeCompleteCallback(
2079 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002080 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002081 EXPECT_TRUE(initialized_);
2082 callback_registered_ = true;
2083 return 0;
2084 }
2085
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002086 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002087 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002088 EXPECT_TRUE(IsReadyForEncode());
2089 EXPECT_FALSE(released_);
2090 initialized_ = false;
2091 callback_registered_ = false;
2092 released_ = true;
2093 ++num_releases_;
2094 return 0;
2095 }
2096
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002097 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002098 EXPECT_TRUE(IsReadyForEncode());
2099 return 0;
2100 }
2101
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002102 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002103 EXPECT_TRUE(IsReadyForEncode());
2104 return 0;
2105 }
2106
stefanff483612015-12-21 03:14:00 -08002107 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002108 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002109 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002110 stream_ = send_stream;
2111 }
2112
stefanff483612015-12-21 03:14:00 -08002113 void ModifyVideoConfigs(
2114 VideoSendStream::Config* send_config,
2115 std::vector<VideoReceiveStream::Config>* receive_configs,
2116 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002117 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07002118 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002119 }
2120
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002121 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002122 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
Per21d45d22016-10-30 21:37:57 +01002123 EXPECT_EQ(0u, num_releases());
perkj26091b12016-09-01 01:17:40 -07002124 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
Per21d45d22016-10-30 21:37:57 +01002125 EXPECT_EQ(0u, num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002126 stream_->Stop();
2127 // Encoder should not be released before destroying the VideoSendStream.
2128 EXPECT_FALSE(IsReleased());
2129 EXPECT_TRUE(IsReadyForEncode());
2130 stream_->Start();
2131 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002132 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002133 }
2134
Peter Boströmf2f82832015-05-01 13:00:41 +02002135 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002136 VideoSendStream* stream_;
2137 bool initialized_ GUARDED_BY(crit_);
2138 bool callback_registered_ GUARDED_BY(crit_);
2139 size_t num_releases_ GUARDED_BY(crit_);
2140 bool released_ GUARDED_BY(crit_);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002141 VideoEncoderConfig encoder_config_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002142 } test_encoder;
2143
stefane74eef12016-01-08 06:47:13 -08002144 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002145
2146 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002147 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002148}
2149
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002150TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2151 class VideoCodecConfigObserver : public test::SendTest,
2152 public test::FakeEncoder {
2153 public:
2154 VideoCodecConfigObserver()
2155 : SendTest(kDefaultTimeoutMs),
2156 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002157 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002158 num_initializations_(0),
2159 stream_(nullptr) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002160
2161 private:
stefanff483612015-12-21 03:14:00 -08002162 void ModifyVideoConfigs(
2163 VideoSendStream::Config* send_config,
2164 std::vector<VideoReceiveStream::Config>* receive_configs,
2165 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002166 send_config->encoder_settings.encoder = this;
sprangf24a0642017-02-28 13:23:26 -08002167 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002168 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002169 }
2170
stefanff483612015-12-21 03:14:00 -08002171 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002172 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002173 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002174 stream_ = send_stream;
2175 }
2176
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002177 int32_t InitEncode(const VideoCodec* config,
2178 int32_t number_of_cores,
2179 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002180 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002181 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002182 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002183 } else {
2184 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002185 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002186 }
2187 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002188 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002189 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2190 }
2191
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002192 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002193 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002194 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002195
sprangf24a0642017-02-28 13:23:26 -08002196 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002197 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002198 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002199 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002200 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2201 "new encoder settings.";
2202 }
2203
sprangf24a0642017-02-28 13:23:26 -08002204 const uint32_t kFirstMaxBitrateBps = 1000000;
2205 const uint32_t kSecondMaxBitrateBps = 2000000;
2206
pbos14fe7082016-04-20 06:35:56 -07002207 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002208 size_t num_initializations_;
2209 VideoSendStream* stream_;
2210 VideoEncoderConfig encoder_config_;
2211 } test;
2212
stefane74eef12016-01-08 06:47:13 -08002213 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002214}
2215
Peter Boström53eda3d2015-03-27 15:53:18 +01002216static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
2217template <typename T>
2218class VideoCodecConfigObserver : public test::SendTest,
2219 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002220 public:
2221 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2222 const char* codec_name)
2223 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2224 FakeEncoder(Clock::GetRealTimeClock()),
2225 video_codec_type_(video_codec_type),
2226 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002227 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002228 num_initializations_(0),
2229 stream_(nullptr) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002230 memset(&encoder_settings_, 0, sizeof(encoder_settings_));
2231 }
2232
2233 private:
perkjfa10b552016-10-02 23:45:26 -07002234 class VideoStreamFactory
2235 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2236 public:
2237 VideoStreamFactory() {}
2238
2239 private:
2240 std::vector<VideoStream> CreateEncoderStreams(
2241 int width,
2242 int height,
2243 const VideoEncoderConfig& encoder_config) override {
2244 std::vector<VideoStream> streams =
2245 test::CreateVideoStreams(width, height, encoder_config);
2246 for (size_t i = 0; i < streams.size(); ++i) {
2247 streams[i].temporal_layer_thresholds_bps.resize(
2248 kVideoCodecConfigObserverNumberOfTemporalLayers - 1);
2249 }
2250 return streams;
2251 }
2252 };
2253
stefanff483612015-12-21 03:14:00 -08002254 void ModifyVideoConfigs(
2255 VideoSendStream::Config* send_config,
2256 std::vector<VideoReceiveStream::Config>* receive_configs,
2257 VideoEncoderConfig* encoder_config) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002258 send_config->encoder_settings.encoder = this;
2259 send_config->encoder_settings.payload_name = codec_name_;
2260
kthelgason29a44e32016-09-27 03:52:02 -07002261 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002262 encoder_config->video_stream_factory =
2263 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002264 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002265 }
2266
stefanff483612015-12-21 03:14:00 -08002267 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002268 VideoSendStream* send_stream,
2269 const std::vector<VideoReceiveStream*>& receive_streams) override {
2270 stream_ = send_stream;
2271 }
2272
2273 int32_t InitEncode(const VideoCodec* config,
2274 int32_t number_of_cores,
2275 size_t max_payload_size) override {
2276 EXPECT_EQ(video_codec_type_, config->codecType);
2277 VerifyCodecSpecifics(*config);
2278 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002279 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002280 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2281 }
2282
2283 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002284 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2285 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002286
2287 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002288 EXPECT_TRUE(
2289 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002290 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002291
2292 encoder_settings_.frameDroppingOn = true;
kthelgason29a44e32016-09-27 03:52:02 -07002293 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002294 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002295 ASSERT_TRUE(
2296 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002297 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002298 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2299 "new encoder settings.";
2300 }
2301
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002302 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002303 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002304 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002305 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2306 return 0;
2307 }
2308
2309 T encoder_settings_;
2310 const VideoCodecType video_codec_type_;
2311 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002312 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002313 size_t num_initializations_;
2314 VideoSendStream* stream_;
2315 VideoEncoderConfig encoder_config_;
2316};
2317
2318template <>
2319void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2320 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002321 EXPECT_EQ(
2322 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002323}
kthelgason29a44e32016-09-27 03:52:02 -07002324
2325template <>
2326rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2327VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2328 return new rtc::RefCountedObject<
2329 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2330}
2331
Peter Boström53eda3d2015-03-27 15:53:18 +01002332template <>
2333void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2334 const VideoCodec& config) const {
2335 // Check that the number of temporal layers has propagated properly to
2336 // VideoCodec.
2337 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002338 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002339
2340 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2341 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2342 config.simulcastStream[i].numberOfTemporalLayers);
2343 }
2344
2345 // Set expected temporal layers as they should have been set when
Erik Språng08127a92016-11-16 16:41:30 +01002346 // reconfiguring the encoder and not match the set config. Also copy the
2347 // TemporalLayersFactory pointer that has been injected by ViEEncoder.
Peter Boström53eda3d2015-03-27 15:53:18 +01002348 VideoCodecVP8 encoder_settings = encoder_settings_;
2349 encoder_settings.numberOfTemporalLayers =
2350 kVideoCodecConfigObserverNumberOfTemporalLayers;
Erik Språng08127a92016-11-16 16:41:30 +01002351 encoder_settings.tl_factory = config.VP8().tl_factory;
hta257dc392016-10-25 09:05:06 -07002352 EXPECT_EQ(
2353 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002354}
kthelgason29a44e32016-09-27 03:52:02 -07002355
2356template <>
2357rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2358VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2359 return new rtc::RefCountedObject<
2360 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2361}
2362
Peter Boström53eda3d2015-03-27 15:53:18 +01002363template <>
2364void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2365 const VideoCodec& config) const {
2366 // Check that the number of temporal layers has propagated properly to
2367 // VideoCodec.
2368 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002369 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002370
2371 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2372 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2373 config.simulcastStream[i].numberOfTemporalLayers);
2374 }
2375
2376 // Set expected temporal layers as they should have been set when
2377 // reconfiguring the encoder and not match the set config.
2378 VideoCodecVP9 encoder_settings = encoder_settings_;
2379 encoder_settings.numberOfTemporalLayers =
2380 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002381 EXPECT_EQ(
2382 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002383}
2384
kthelgason29a44e32016-09-27 03:52:02 -07002385template <>
2386rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2387VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2388 return new rtc::RefCountedObject<
2389 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2390}
2391
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002392TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002393 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002394 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002395}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002396
Peter Boström53eda3d2015-03-27 15:53:18 +01002397TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2398 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002399 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002400}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002401
Peter Boström53eda3d2015-03-27 15:53:18 +01002402TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2403 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002404 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002405}
2406
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002407TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002408 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002409 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002410 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2411 rtp_packets_sent_(0),
2412 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002413
2414 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002415 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002416 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002417 RTPHeader header;
2418 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002419 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002420 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2421 return SEND_PACKET;
2422 }
2423
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002424 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002425 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002426 test::RtcpPacketParser parser;
2427 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002428
danilchap3dc929e2016-11-02 08:21:59 -07002429 if (parser.sender_report()->num_packets() > 0) {
2430 // Only compare sent media bytes if SenderPacketCount matches the
2431 // number of sent rtp packets (a new rtp packet could be sent before
2432 // the rtcp packet).
2433 if (parser.sender_report()->sender_octet_count() > 0 &&
2434 parser.sender_report()->sender_packet_count() ==
2435 rtp_packets_sent_) {
2436 EXPECT_EQ(media_bytes_sent_,
2437 parser.sender_report()->sender_octet_count());
2438 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002439 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002440 }
2441
2442 return SEND_PACKET;
2443 }
2444
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002445 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002446 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002447 }
2448
stefan4b569042015-11-11 06:39:57 -08002449 rtc::CriticalSection crit_;
2450 size_t rtp_packets_sent_ GUARDED_BY(&crit_);
2451 size_t media_bytes_sent_ GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002452 } test;
2453
stefane74eef12016-01-08 06:47:13 -08002454 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002455}
2456
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002457TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
2458 static const int kScreencastTargetBitrateKbps = 200;
perkjfa10b552016-10-02 23:45:26 -07002459
2460 class VideoStreamFactory
2461 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2462 public:
2463 VideoStreamFactory() {}
2464
2465 private:
2466 std::vector<VideoStream> CreateEncoderStreams(
2467 int width,
2468 int height,
2469 const VideoEncoderConfig& encoder_config) override {
2470 std::vector<VideoStream> streams =
2471 test::CreateVideoStreams(width, height, encoder_config);
2472 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
2473 streams[0].temporal_layer_thresholds_bps.push_back(
2474 kScreencastTargetBitrateKbps * 1000);
2475 return streams;
2476 }
2477 };
2478
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002479 class ScreencastTargetBitrateTest : public test::SendTest,
2480 public test::FakeEncoder {
2481 public:
2482 ScreencastTargetBitrateTest()
2483 : SendTest(kDefaultTimeoutMs),
2484 test::FakeEncoder(Clock::GetRealTimeClock()) {}
2485
2486 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002487 int32_t InitEncode(const VideoCodec* config,
2488 int32_t number_of_cores,
2489 size_t max_payload_size) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002490 EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps),
2491 config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002492 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002493 return test::FakeEncoder::InitEncode(
2494 config, number_of_cores, max_payload_size);
2495 }
stefanff483612015-12-21 03:14:00 -08002496 void ModifyVideoConfigs(
2497 VideoSendStream::Config* send_config,
2498 std::vector<VideoReceiveStream::Config>* receive_configs,
2499 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002500 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002501 EXPECT_EQ(1u, encoder_config->number_of_streams);
2502 encoder_config->video_stream_factory =
2503 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002504 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002505 }
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())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002509 << "Timed out while waiting for the encoder to be initialized.";
2510 }
2511 } test;
2512
stefane74eef12016-01-08 06:47:13 -08002513 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002514}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002515
philipelc6957c72016-04-28 15:52:49 +02002516TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002517 // These are chosen to be "kind of odd" to not be accidentally checked against
2518 // default values.
2519 static const int kMinBitrateKbps = 137;
2520 static const int kStartBitrateKbps = 345;
2521 static const int kLowerMaxBitrateKbps = 312;
2522 static const int kMaxBitrateKbps = 413;
2523 static const int kIncreasedStartBitrateKbps = 451;
2524 static const int kIncreasedMaxBitrateKbps = 597;
2525 class EncoderBitrateThresholdObserver : public test::SendTest,
2526 public test::FakeEncoder {
2527 public:
2528 EncoderBitrateThresholdObserver()
2529 : SendTest(kDefaultTimeoutMs),
2530 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002531 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002532 bitrate_changed_event_(false, false),
2533 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002534 num_initializations_(0),
2535 call_(nullptr),
2536 send_stream_(nullptr) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002537
2538 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002539 int32_t InitEncode(const VideoCodec* codecSettings,
2540 int32_t numberOfCores,
2541 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002542 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2543 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002544 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002545 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2546 codecSettings->minBitrate);
2547 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2548 codecSettings->startBitrate);
2549 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2550 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002551 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002552 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002553 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2554 codecSettings->maxBitrate);
2555 // The start bitrate should be kept (-1) and capped to the max bitrate.
2556 // Since this is not an end-to-end call no receiver should have been
2557 // returning a REMB that could lower this estimate.
2558 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002559 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002560 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2561 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002562 // The start bitrate will be whatever the rate BitRateController
2563 // has currently configured but in the span of the set max and min
2564 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002565 }
2566 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002567 init_encode_event_.Set();
2568
pbos@webrtc.org00873182014-11-25 14:03:34 +00002569 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2570 maxPayloadSize);
2571 }
2572
Erik Språng08127a92016-11-16 16:41:30 +01002573 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
2574 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002575 {
2576 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002577 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2578 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002579 }
Erik Språng08127a92016-11-16 16:41:30 +01002580 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002581 }
2582 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002583 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002584 }
2585
2586 void WaitForSetRates(uint32_t expected_bitrate) {
2587 EXPECT_TRUE(
2588 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2589 << "Timed out while waiting encoder rate to be set.";
2590 rtc::CritScope lock(&crit_);
2591 EXPECT_EQ(expected_bitrate, target_bitrate_);
2592 }
2593
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002594 Call::Config GetSenderCallConfig() override {
philipel4fb651d2017-04-10 03:54:05 -07002595 Call::Config config(event_log_.get());
Stefan Holmere5904162015-03-26 11:11:06 +01002596 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2597 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2598 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002599 return config;
2600 }
2601
perkjfa10b552016-10-02 23:45:26 -07002602 class VideoStreamFactory
2603 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2604 public:
2605 explicit VideoStreamFactory(int min_bitrate_bps)
2606 : min_bitrate_bps_(min_bitrate_bps) {}
2607
2608 private:
2609 std::vector<VideoStream> CreateEncoderStreams(
2610 int width,
2611 int height,
2612 const VideoEncoderConfig& encoder_config) override {
2613 std::vector<VideoStream> streams =
2614 test::CreateVideoStreams(width, height, encoder_config);
2615 streams[0].min_bitrate_bps = min_bitrate_bps_;
2616 return streams;
2617 }
2618
2619 const int min_bitrate_bps_;
2620 };
2621
stefanff483612015-12-21 03:14:00 -08002622 void ModifyVideoConfigs(
2623 VideoSendStream::Config* send_config,
2624 std::vector<VideoReceiveStream::Config>* receive_configs,
2625 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002626 send_config->encoder_settings.encoder = this;
2627 // Set bitrates lower/higher than min/max to make sure they are properly
2628 // capped.
perkjfa10b552016-10-02 23:45:26 -07002629 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2630 // Create a new StreamFactory to be able to set
2631 // |VideoStream.min_bitrate_bps|.
2632 encoder_config->video_stream_factory =
2633 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002634 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002635 }
2636
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002637 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002638 call_ = sender_call;
2639 }
2640
stefanff483612015-12-21 03:14:00 -08002641 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002642 VideoSendStream* send_stream,
2643 const std::vector<VideoReceiveStream*>& receive_streams) override {
2644 send_stream_ = send_stream;
2645 }
2646
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002647 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002648 ASSERT_TRUE(
2649 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002650 << "Timed out while waiting for encoder to be configured.";
2651 WaitForSetRates(kStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002652 Call::Config::BitrateConfig bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002653 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2654 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2655 call_->SetBitrateConfig(bitrate_config);
perkj26091b12016-09-01 01:17:40 -07002656 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2657 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002658 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002659 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002660 ASSERT_TRUE(
2661 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002662 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002663 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002664 WaitForSetRates(kLowerMaxBitrateKbps);
2665
2666 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2667 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2668 ASSERT_TRUE(
2669 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002670 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002671 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002672 // Expected target bitrate is the start bitrate set in the call to
2673 // call_->SetBitrateConfig.
2674 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002675 }
2676
pbos14fe7082016-04-20 06:35:56 -07002677 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002678 rtc::Event bitrate_changed_event_;
2679 rtc::CriticalSection crit_;
2680 uint32_t target_bitrate_ GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002681
pbos@webrtc.org00873182014-11-25 14:03:34 +00002682 int num_initializations_;
2683 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002684 webrtc::VideoSendStream* send_stream_;
2685 webrtc::VideoEncoderConfig encoder_config_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002686 } test;
2687
stefane74eef12016-01-08 06:47:13 -08002688 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002689}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002690
2691TEST_F(VideoSendStreamTest, ReportsSentResolution) {
2692 static const size_t kNumStreams = 3;
2693 // Unusual resolutions to make sure that they are the ones being reported.
2694 static const struct {
2695 int width;
2696 int height;
2697 } kEncodedResolution[kNumStreams] = {
2698 {241, 181}, {300, 121}, {121, 221}};
2699 class ScreencastTargetBitrateTest : public test::SendTest,
2700 public test::FakeEncoder {
2701 public:
2702 ScreencastTargetBitrateTest()
2703 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002704 test::FakeEncoder(Clock::GetRealTimeClock()),
2705 send_stream_(nullptr) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002706
2707 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002708 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002709 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002710 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002711 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002712 specifics.codecType = kVideoCodecGeneric;
2713
2714 uint8_t buffer[16] = {0};
2715 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
2716 encoded._timeStamp = input_image.timestamp();
2717 encoded.capture_time_ms_ = input_image.render_time_ms();
2718
2719 for (size_t i = 0; i < kNumStreams; ++i) {
2720 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
2721 encoded._frameType = (*frame_types)[i];
2722 encoded._encodedWidth = kEncodedResolution[i].width;
2723 encoded._encodedHeight = kEncodedResolution[i].height;
brandtre78d2662017-01-16 05:57:16 -08002724 EncodedImageCallback* callback;
2725 {
2726 rtc::CritScope cs(&crit_sect_);
2727 callback = callback_;
2728 }
2729 RTC_DCHECK(callback);
2730 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07002731 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002732 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07002733 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002734 }
2735
Peter Boström5811a392015-12-10 13:02:50 +01002736 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002737 return 0;
2738 }
stefanff483612015-12-21 03:14:00 -08002739 void ModifyVideoConfigs(
2740 VideoSendStream::Config* send_config,
2741 std::vector<VideoReceiveStream::Config>* receive_configs,
2742 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002743 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002744 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002745 }
2746
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002747 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002748
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002749 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002750 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002751 << "Timed out while waiting for the encoder to send one frame.";
2752 VideoSendStream::Stats stats = send_stream_->GetStats();
2753
2754 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002755 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002756 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002757 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002758 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002759 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002760 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002761 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
2762 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002763 }
2764 }
2765
stefanff483612015-12-21 03:14:00 -08002766 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002767 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002768 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002769 send_stream_ = send_stream;
2770 }
2771
2772 VideoSendStream* send_stream_;
2773 } test;
2774
stefane74eef12016-01-08 06:47:13 -08002775 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002776}
philipel0f9af012015-09-01 07:01:51 -07002777
Peter Boström12996152016-05-14 02:03:18 +02002778#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01002779class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07002780 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01002781 Vp9HeaderObserver()
2782 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
philipel7fabd462015-09-03 04:42:32 -07002783 vp9_encoder_(VP9Encoder::Create()),
Åsa Perssonff24c042015-12-04 10:58:08 +01002784 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
2785 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07002786 frames_sent_(0),
2787 expected_width_(0),
2788 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07002789
stefanff483612015-12-21 03:14:00 -08002790 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07002791 VideoSendStream::Config* send_config,
2792 std::vector<VideoReceiveStream::Config>* receive_configs,
2793 VideoEncoderConfig* encoder_config) {}
2794
Åsa Perssonff24c042015-12-04 10:58:08 +01002795 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07002796
2797 private:
minyue20c84cc2017-04-10 16:57:57 -07002798 const int kVp9PayloadType = test::CallTest::kVideoSendPayloadType;
philipel0f9af012015-09-01 07:01:51 -07002799
perkjfa10b552016-10-02 23:45:26 -07002800 class VideoStreamFactory
2801 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2802 public:
2803 explicit VideoStreamFactory(size_t number_of_temporal_layers)
2804 : number_of_temporal_layers_(number_of_temporal_layers) {}
2805
2806 private:
2807 std::vector<VideoStream> CreateEncoderStreams(
2808 int width,
2809 int height,
2810 const VideoEncoderConfig& encoder_config) override {
2811 std::vector<VideoStream> streams =
2812 test::CreateVideoStreams(width, height, encoder_config);
2813 streams[0].temporal_layer_thresholds_bps.resize(
2814 number_of_temporal_layers_ - 1);
2815 return streams;
2816 }
2817
2818 const size_t number_of_temporal_layers_;
2819 };
2820
stefanff483612015-12-21 03:14:00 -08002821 void ModifyVideoConfigs(
2822 VideoSendStream::Config* send_config,
2823 std::vector<VideoReceiveStream::Config>* receive_configs,
2824 VideoEncoderConfig* encoder_config) override {
philipel7fabd462015-09-03 04:42:32 -07002825 send_config->encoder_settings.encoder = vp9_encoder_.get();
philipel0f9af012015-09-01 07:01:51 -07002826 send_config->encoder_settings.payload_name = "VP9";
2827 send_config->encoder_settings.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08002828 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07002829 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
2830 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07002831 EXPECT_EQ(1u, encoder_config->number_of_streams);
2832 encoder_config->video_stream_factory =
2833 new rtc::RefCountedObject<VideoStreamFactory>(
2834 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07002835 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07002836 }
2837
perkjfa10b552016-10-02 23:45:26 -07002838 void ModifyVideoCaptureStartResolution(int* width,
2839 int* height,
2840 int* frame_rate) override {
2841 expected_width_ = *width;
2842 expected_height_ = *height;
2843 }
2844
philipel0f9af012015-09-01 07:01:51 -07002845 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002846 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
2847 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002848 }
2849
2850 Action OnSendRtp(const uint8_t* packet, size_t length) override {
2851 RTPHeader header;
2852 EXPECT_TRUE(parser_->Parse(packet, length, &header));
2853
Åsa Perssonff24c042015-12-04 10:58:08 +01002854 EXPECT_EQ(kVp9PayloadType, header.payloadType);
2855 const uint8_t* payload = packet + header.headerLength;
2856 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07002857
Åsa Perssonff24c042015-12-04 10:58:08 +01002858 bool new_packet = packets_sent_ == 0 ||
2859 IsNewerSequenceNumber(header.sequenceNumber,
2860 last_header_.sequenceNumber);
2861 if (payload_length > 0 && new_packet) {
2862 RtpDepacketizer::ParsedPayload parsed;
2863 RtpDepacketizerVp9 depacketizer;
2864 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
2865 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
2866 // Verify common fields for all configurations.
2867 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
2868 CompareConsecutiveFrames(header, parsed.type.Video);
2869 // Verify configuration specific settings.
2870 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07002871
Åsa Perssonff24c042015-12-04 10:58:08 +01002872 ++packets_sent_;
2873 if (header.markerBit) {
2874 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002875 }
Åsa Perssonff24c042015-12-04 10:58:08 +01002876 last_header_ = header;
2877 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07002878 }
philipel0f9af012015-09-01 07:01:51 -07002879 return SEND_PACKET;
2880 }
2881
philipel7fabd462015-09-03 04:42:32 -07002882 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01002883 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
2884 if (last_vp9_.picture_id > vp9.picture_id) {
2885 return vp9.picture_id == 0; // Wrap.
2886 } else {
2887 return vp9.picture_id == last_vp9_.picture_id + 1;
2888 }
2889 }
2890
2891 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01002892 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
2893 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
2894 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
2895 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
2896 vp9.spatial_idx);
2897 }
2898
2899 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
2900 uint8_t num_layers) const {
2901 switch (num_layers) {
2902 case 0:
2903 VerifyTemporalLayerStructure0(vp9);
2904 break;
2905 case 1:
2906 VerifyTemporalLayerStructure1(vp9);
2907 break;
2908 case 2:
2909 VerifyTemporalLayerStructure2(vp9);
2910 break;
2911 case 3:
2912 VerifyTemporalLayerStructure3(vp9);
2913 break;
2914 default:
2915 RTC_NOTREACHED();
2916 }
2917 }
2918
2919 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
2920 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
2921 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
2922 EXPECT_FALSE(vp9.temporal_up_switch);
2923 }
2924
2925 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
2926 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2927 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
2928 EXPECT_FALSE(vp9.temporal_up_switch);
2929 }
2930
2931 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
2932 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2933 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
2934 EXPECT_LE(vp9.temporal_idx, 1);
2935 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
2936 if (IsNewPictureId(vp9)) {
2937 uint8_t expected_tid =
2938 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
2939 EXPECT_EQ(expected_tid, vp9.temporal_idx);
2940 }
2941 }
2942
2943 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
2944 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2945 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
2946 EXPECT_LE(vp9.temporal_idx, 2);
2947 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
2948 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
2949 switch (vp9.temporal_idx) {
2950 case 0:
2951 EXPECT_EQ(2, last_vp9_.temporal_idx);
2952 EXPECT_FALSE(vp9.temporal_up_switch);
2953 break;
2954 case 1:
2955 EXPECT_EQ(2, last_vp9_.temporal_idx);
2956 EXPECT_TRUE(vp9.temporal_up_switch);
2957 break;
2958 case 2:
2959 EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
2960 break;
2961 }
2962 }
2963 }
2964
2965 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
2966 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
2967 return;
2968
2969 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
2970 if (vp9.temporal_idx == 0)
2971 ++expected_tl0_idx;
2972 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
2973 }
2974
2975 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
2976 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
2977 }
2978
2979 // Flexible mode (F=1): Non-flexible mode (F=0):
2980 //
2981 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2982 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
2983 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2984 // I: |M| PICTURE ID | I: |M| PICTURE ID |
2985 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2986 // M: | EXTENDED PID | M: | EXTENDED PID |
2987 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2988 // L: | T |U| S |D| L: | T |U| S |D|
2989 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2990 // P,F: | P_DIFF |X|N| | TL0PICIDX |
2991 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2992 // X: |EXTENDED P_DIFF| V: | SS .. |
2993 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2994 // V: | SS .. |
2995 // +-+-+-+-+-+-+-+-+
2996 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
2997 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
2998 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
2999 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
3000 EXPECT_GE(vp9.spatial_idx, 0); // S
3001 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
3002 if (vp9.ss_data_available) // V
3003 VerifySsData(vp9);
3004
3005 if (frames_sent_ == 0)
3006 EXPECT_FALSE(vp9.inter_pic_predicted); // P
3007
3008 if (!vp9.inter_pic_predicted) {
3009 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
3010 EXPECT_FALSE(vp9.temporal_up_switch);
3011 }
3012 }
3013
3014 // Scalability structure (SS).
3015 //
3016 // +-+-+-+-+-+-+-+-+
3017 // V: | N_S |Y|G|-|-|-|
3018 // +-+-+-+-+-+-+-+-+
3019 // Y: | WIDTH | N_S + 1 times
3020 // +-+-+-+-+-+-+-+-+
3021 // | HEIGHT |
3022 // +-+-+-+-+-+-+-+-+
3023 // G: | N_G |
3024 // +-+-+-+-+-+-+-+-+
3025 // N_G: | T |U| R |-|-| N_G times
3026 // +-+-+-+-+-+-+-+-+
3027 // | P_DIFF | R times
3028 // +-+-+-+-+-+-+-+-+
3029 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
3030 EXPECT_TRUE(vp9.ss_data_available); // V
3031 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
3032 vp9.num_spatial_layers);
3033 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07003034 int expected_width = expected_width_;
3035 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02003036 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003037 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
3038 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
3039 expected_width /= 2;
3040 expected_height /= 2;
3041 }
3042 }
3043
3044 void CompareConsecutiveFrames(const RTPHeader& header,
3045 const RTPVideoHeader& video) const {
3046 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
3047
3048 bool new_frame = packets_sent_ == 0 ||
3049 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003050 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003051 if (!new_frame) {
3052 EXPECT_FALSE(last_header_.markerBit);
3053 EXPECT_EQ(last_header_.timestamp, header.timestamp);
3054 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
3055 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
3056 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
3057 VerifySpatialIdxWithinFrame(vp9);
3058 return;
3059 }
3060 // New frame.
3061 EXPECT_TRUE(vp9.beginning_of_frame);
3062
3063 // Compare with last packet in previous frame.
3064 if (frames_sent_ == 0)
3065 return;
3066 EXPECT_TRUE(last_vp9_.end_of_frame);
3067 EXPECT_TRUE(last_header_.markerBit);
3068 EXPECT_TRUE(ContinuousPictureId(vp9));
3069 VerifyTl0Idx(vp9);
3070 }
3071
kwiberg27f982b2016-03-01 11:52:33 -08003072 std::unique_ptr<VP9Encoder> vp9_encoder_;
philipel0f9af012015-09-01 07:01:51 -07003073 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003074 webrtc::VideoEncoderConfig encoder_config_;
3075 RTPHeader last_header_;
3076 RTPVideoHeaderVP9 last_vp9_;
3077 size_t packets_sent_;
3078 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003079 int expected_width_;
3080 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003081};
3082
Åsa Perssonff24c042015-12-04 10:58:08 +01003083TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
3084 const uint8_t kNumTemporalLayers = 1;
3085 const uint8_t kNumSpatialLayers = 1;
3086 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3087}
3088
3089TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
3090 const uint8_t kNumTemporalLayers = 2;
3091 const uint8_t kNumSpatialLayers = 1;
3092 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3093}
3094
3095TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
3096 const uint8_t kNumTemporalLayers = 3;
3097 const uint8_t kNumSpatialLayers = 1;
3098 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3099}
3100
3101TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
3102 const uint8_t kNumTemporalLayers = 1;
3103 const uint8_t kNumSpatialLayers = 2;
3104 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3105}
3106
3107TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3108 const uint8_t kNumTemporalLayers = 2;
3109 const uint8_t kNumSpatialLayers = 2;
3110 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3111}
3112
3113TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3114 const uint8_t kNumTemporalLayers = 3;
3115 const uint8_t kNumSpatialLayers = 2;
3116 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3117}
3118
3119void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3120 uint8_t num_spatial_layers) {
3121 static const size_t kNumFramesToSend = 100;
3122 // Set to < kNumFramesToSend and coprime to length of temporal layer
3123 // structures to verify temporal id reset on key frame.
3124 static const int kKeyFrameInterval = 31;
3125 class NonFlexibleMode : public Vp9HeaderObserver {
3126 public:
3127 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3128 : num_temporal_layers_(num_temporal_layers),
3129 num_spatial_layers_(num_spatial_layers),
3130 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
stefanff483612015-12-21 03:14:00 -08003131 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003132 VideoSendStream::Config* send_config,
3133 std::vector<VideoReceiveStream::Config>* receive_configs,
3134 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003135 vp9_settings_.flexibleMode = false;
3136 vp9_settings_.frameDroppingOn = false;
3137 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3138 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3139 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003140 }
3141
Åsa Perssonff24c042015-12-04 10:58:08 +01003142 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
3143 bool ss_data_expected = !vp9.inter_pic_predicted &&
3144 vp9.beginning_of_frame && vp9.spatial_idx == 0;
3145 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
3146 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted); // D
asapersson38bb8ad2015-12-14 01:41:19 -08003147 EXPECT_EQ(!vp9.inter_pic_predicted,
3148 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003149
3150 if (IsNewPictureId(vp9)) {
3151 EXPECT_EQ(0, vp9.spatial_idx);
3152 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
3153 }
3154
3155 VerifyFixedTemporalLayerStructure(vp9,
3156 l_field_ ? num_temporal_layers_ : 0);
3157
3158 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003159 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003160 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003161 const uint8_t num_temporal_layers_;
3162 const uint8_t num_spatial_layers_;
3163 const bool l_field_;
3164 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003165
stefane74eef12016-01-08 06:47:13 -08003166 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003167}
3168
asaperssond9f641e2016-01-21 01:11:35 -08003169TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3170 static const size_t kNumFramesToSend = 50;
3171 static const int kWidth = 4;
3172 static const int kHeight = 4;
3173 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3174 void ModifyVideoConfigsHook(
3175 VideoSendStream::Config* send_config,
3176 std::vector<VideoReceiveStream::Config>* receive_configs,
3177 VideoEncoderConfig* encoder_config) override {
3178 vp9_settings_.flexibleMode = false;
3179 vp9_settings_.numberOfTemporalLayers = 1;
3180 vp9_settings_.numberOfSpatialLayers = 1;
3181
perkjfa10b552016-10-02 23:45:26 -07003182 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003183 }
3184
3185 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3186 if (frames_sent_ > kNumFramesToSend)
3187 observation_complete_.Set();
3188 }
perkjfa10b552016-10-02 23:45:26 -07003189
3190 void ModifyVideoCaptureStartResolution(int* width,
3191 int* height,
3192 int* frame_rate) override {
3193 expected_width_ = kWidth;
3194 expected_height_ = kHeight;
3195 *width = kWidth;
3196 *height = kHeight;
3197 }
asaperssond9f641e2016-01-21 01:11:35 -08003198 } test;
3199
3200 RunBaseTest(&test);
3201}
3202
kjellanderf9e2a362017-03-24 12:17:33 -07003203#if defined(WEBRTC_ANDROID)
3204// Crashes on Android; bugs.webrtc.org/7401
3205#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3206#else
3207#define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
3208#endif
3209TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003210 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003211 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003212 VideoSendStream::Config* send_config,
3213 std::vector<VideoReceiveStream::Config>* receive_configs,
3214 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003215 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003216 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003217 vp9_settings_.numberOfTemporalLayers = 1;
3218 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003219 }
3220
Åsa Perssonff24c042015-12-04 10:58:08 +01003221 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3222 EXPECT_TRUE(vp9_header.flexible_mode);
3223 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3224 if (vp9_header.inter_pic_predicted) {
3225 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003226 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003227 }
3228 }
3229 } test;
3230
stefane74eef12016-01-08 06:47:13 -08003231 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003232}
Peter Boström12996152016-05-14 02:03:18 +02003233#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003234
perkj803d97f2016-11-01 11:45:46 -07003235void VideoSendStreamTest::TestRequestSourceRotateVideo(
3236 bool support_orientation_ext) {
philipel4fb651d2017-04-10 03:54:05 -07003237 CreateSenderCall(Call::Config(event_log_.get()));
perkj803d97f2016-11-01 11:45:46 -07003238
3239 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003240 CreateSendConfig(1, 0, 0, &transport);
perkj803d97f2016-11-01 11:45:46 -07003241 video_send_config_.rtp.extensions.clear();
3242 if (support_orientation_ext) {
3243 video_send_config_.rtp.extensions.push_back(
3244 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3245 }
3246
3247 CreateVideoStreams();
3248 test::FrameForwarder forwarder;
3249 video_send_stream_->SetSource(
sprangc5d62e22017-04-02 23:53:04 -07003250 &forwarder, VideoSendStream::DegradationPreference::kMaintainFramerate);
perkj803d97f2016-11-01 11:45:46 -07003251
3252 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3253 support_orientation_ext);
3254
3255 DestroyStreams();
3256}
3257
3258TEST_F(VideoSendStreamTest,
3259 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3260 TestRequestSourceRotateVideo(false);
3261}
3262
3263TEST_F(VideoSendStreamTest,
3264 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3265 TestRequestSourceRotateVideo(true);
3266}
3267
michaelta3328772016-11-29 09:25:03 -08003268// This test verifies that overhead is removed from the bandwidth estimate by
3269// testing that the maximum possible target payload rate is smaller than the
3270// maximum bandwidth estimate by the overhead rate.
michaelt273f31b2017-02-08 08:21:52 -08003271TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003272 test::ScopedFieldTrials override_field_trials(
3273 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3274 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3275 public test::FakeEncoder {
3276 public:
3277 RemoveOverheadFromBandwidthTest()
3278 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3279 FakeEncoder(Clock::GetRealTimeClock()),
3280 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003281 max_bitrate_bps_(0),
3282 first_packet_sent_(false),
3283 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003284
3285 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
3286 uint32_t frameRate) override {
3287 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003288 // Wait for the first sent packet so that videosendstream knows
3289 // rtp_overhead.
3290 if (first_packet_sent_) {
3291 max_bitrate_bps_ = bitrate.get_sum_bps();
3292 bitrate_changed_event_.Set();
3293 }
michaelta3328772016-11-29 09:25:03 -08003294 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3295 }
3296
3297 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3298 call_ = sender_call;
3299 }
3300
3301 void ModifyVideoConfigs(
3302 VideoSendStream::Config* send_config,
3303 std::vector<VideoReceiveStream::Config>* receive_configs,
3304 VideoEncoderConfig* encoder_config) override {
3305 send_config->rtp.max_packet_size = 1200;
3306 send_config->encoder_settings.encoder = this;
3307 EXPECT_FALSE(send_config->rtp.extensions.empty());
3308 }
3309
michaelt192132e2017-01-26 09:05:27 -08003310 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3311 rtc::CritScope lock(&crit_);
3312 first_packet_sent_ = true;
3313 return SEND_PACKET;
3314 }
3315
michaelta3328772016-11-29 09:25:03 -08003316 void PerformTest() override {
michaelta3328772016-11-29 09:25:03 -08003317 Call::Config::BitrateConfig bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003318 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003319 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003320 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003321 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3322 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003323 bitrate_config.min_bitrate_bps = kMinBitrateBps;
michaelta3328772016-11-29 09:25:03 -08003324 call_->SetBitrateConfig(bitrate_config);
michaelt273f31b2017-02-08 08:21:52 -08003325 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
michaelta3328772016-11-29 09:25:03 -08003326
3327 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003328 // overhead of 40B per packet video produces 2240bps overhead.
3329 // So the encoder BW should be set to 57760bps.
3330 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
michaelta3328772016-11-29 09:25:03 -08003331 {
3332 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003333 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003334 }
3335 }
3336
3337 private:
3338 Call* call_;
3339 rtc::CriticalSection crit_;
michaelt192132e2017-01-26 09:05:27 -08003340 uint32_t max_bitrate_bps_ GUARDED_BY(&crit_);
3341 bool first_packet_sent_ GUARDED_BY(&crit_);
3342 rtc::Event bitrate_changed_event_;
michaelta3328772016-11-29 09:25:03 -08003343 } test;
3344
3345 RunBaseTest(&test);
3346}
3347
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003348} // namespace webrtc