blob: 82fb6befe9e83aa0c7d40e109231798c24af548c [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"
ossuf515ab82016-12-07 04:52:58 -080021#include "webrtc/call/call.h"
pbosa96b60b2016-04-18 21:12:48 -070022#include "webrtc/common_video/include/frame_callback.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010023#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
24#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +000025#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
philipel0f9af012015-09-01 07:01:51 -070026#include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h"
magjed509e4fe2016-11-18 01:34:11 -080027#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
philipel7fabd462015-09-03 04:42:32 -070028#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010029#include "webrtc/system_wrappers/include/sleep.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000030#include "webrtc/test/call_test.h"
pbos@webrtc.org709e2972014-03-19 10:59:52 +000031#include "webrtc/test/configurable_frame_size_encoder.h"
Peter Boströmeb66e802015-06-05 11:08:03 +020032#include "webrtc/test/fake_texture_frame.h"
perkja49cbd32016-09-16 07:53:41 -070033#include "webrtc/test/frame_generator.h"
nisse26acec42016-04-15 03:43:39 -070034#include "webrtc/test/frame_utils.h"
kwibergac9f8762016-09-30 22:29:43 -070035#include "webrtc/test/gtest.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000036#include "webrtc/test/null_transport.h"
danilchap3dc929e2016-11-02 08:21:59 -070037#include "webrtc/test/rtcp_packet_parser.h"
pbos@webrtc.org709e2972014-03-19 10:59:52 +000038#include "webrtc/test/testsupport/perf_test.h"
michaelta3328772016-11-29 09:25:03 -080039#include "webrtc/test/field_trial.h"
perkjfa10b552016-10-02 23:45:26 -070040
pbos@webrtc.org273a4142014-12-01 15:23:21 +000041#include "webrtc/video/send_statistics_proxy.h"
charujainbf6a45b2016-11-03 04:21:42 -070042#include "webrtc/video/transport_adapter.h"
Thiago Farina9bfe3da2015-04-10 12:52:13 +020043#include "webrtc/video_frame.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000044#include "webrtc/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000045
46namespace webrtc {
47
sprang@webrtc.org346094c2014-02-18 08:40:33 +000048enum VideoFormat { kGeneric, kVP8, };
49
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070050void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
51 const std::vector<VideoFrame>& frames2);
52VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000053
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000054class VideoSendStreamTest : public test::CallTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000055 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000056 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000057 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000058 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010059
60 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
61 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -070062
63 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000064};
65
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000066TEST_F(VideoSendStreamTest, CanStartStartedStream) {
skvlad11a9cbf2016-10-07 11:53:05 -070067 CreateSenderCall(Call::Config(&event_log_));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000068
solenberg4fbae2b2015-08-28 04:07:10 -070069 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -080070 CreateSendConfig(1, 0, 0, &transport);
Stefan Holmer9fea80f2016-01-07 17:43:18 +010071 CreateVideoStreams();
stefanff483612015-12-21 03:14:00 -080072 video_send_stream_->Start();
73 video_send_stream_->Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000074 DestroyStreams();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000075}
76
77TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
skvlad11a9cbf2016-10-07 11:53:05 -070078 CreateSenderCall(Call::Config(&event_log_));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000079
solenberg4fbae2b2015-08-28 04:07:10 -070080 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -080081 CreateSendConfig(1, 0, 0, &transport);
Stefan Holmer9fea80f2016-01-07 17:43:18 +010082 CreateVideoStreams();
stefanff483612015-12-21 03:14:00 -080083 video_send_stream_->Stop();
84 video_send_stream_->Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000085 DestroyStreams();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000086}
87
pbos@webrtc.org013d9942013-08-22 09:42:17 +000088TEST_F(VideoSendStreamTest, SupportsCName) {
89 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000090 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000091 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000092 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +000093
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000094 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000095 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
danilchap3dc929e2016-11-02 08:21:59 -070096 test::RtcpPacketParser parser;
97 EXPECT_TRUE(parser.Parse(packet, length));
98 if (parser.sdes()->num_packets() > 0) {
99 EXPECT_EQ(1u, parser.sdes()->chunks().size());
100 EXPECT_EQ(kCName, parser.sdes()->chunks()[0].cname);
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000101
danilchap3dc929e2016-11-02 08:21:59 -0700102 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000103 }
104
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000105 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000106 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000107
stefanff483612015-12-21 03:14:00 -0800108 void ModifyVideoConfigs(
109 VideoSendStream::Config* send_config,
110 std::vector<VideoReceiveStream::Config>* receive_configs,
111 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000112 send_config->rtp.c_name = kCName;
113 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000114
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000115 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100116 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000117 }
118 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000119
stefane74eef12016-01-08 06:47:13 -0800120 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000121}
122
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000123TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000124 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000125 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000126 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000127 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100128 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000129 }
130
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000131 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000132 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000133 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000134
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000135 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
136 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
137 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700138 if (header.extension.absoluteSendTime != 0) {
139 // Wait for at least one packet with a non-zero send time. The send time
140 // is a 16-bit value derived from the system clock, and it is valid
141 // for a packet to have a zero send time. To tell that from an
142 // unpopulated value we'll wait for a packet with non-zero send time.
143 observation_complete_.Set();
144 } else {
145 LOG(LS_WARNING) << "Got a packet with zero absoluteSendTime, waiting"
146 " for another packet...";
147 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000148
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000149 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000150 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000151
stefanff483612015-12-21 03:14:00 -0800152 void ModifyVideoConfigs(
153 VideoSendStream::Config* send_config,
154 std::vector<VideoReceiveStream::Config>* receive_configs,
155 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200156 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100157 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700158 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000159 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000160
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000161 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100162 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000163 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000164 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000165
stefane74eef12016-01-08 06:47:13 -0800166 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000167}
168
pbos@webrtc.org29023282013-09-11 10:14:56 +0000169TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000170 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000171 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000172 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000173 TransmissionTimeOffsetObserver()
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000174 : SendTest(kDefaultTimeoutMs),
175 encoder_(Clock::GetRealTimeClock(), kEncodeDelayMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000176 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100177 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000178 }
179
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000180 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000181 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000182 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000183 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000184
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000185 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
186 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000187 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000188 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100189 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000190
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000191 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000192 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000193
stefanff483612015-12-21 03:14:00 -0800194 void ModifyVideoConfigs(
195 VideoSendStream::Config* send_config,
196 std::vector<VideoReceiveStream::Config>* receive_configs,
197 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000198 send_config->encoder_settings.encoder = &encoder_;
Stefan Holmer12952972015-10-29 15:13:24 +0100199 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700200 send_config->rtp.extensions.push_back(RtpExtension(
201 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000202 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000203
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000204 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100205 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000206 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000207
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000208 test::DelayedEncoder encoder_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000209 } test;
210
stefane74eef12016-01-08 06:47:13 -0800211 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000212}
213
sprang867fb522015-08-03 04:38:41 -0700214TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700215 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700216 class TransportWideSequenceNumberObserver : public test::SendTest {
217 public:
218 TransportWideSequenceNumberObserver()
219 : SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) {
220 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
221 kRtpExtensionTransportSequenceNumber, kExtensionId));
222 }
223
224 private:
225 Action OnSendRtp(const uint8_t* packet, size_t length) override {
226 RTPHeader header;
227 EXPECT_TRUE(parser_->Parse(packet, length, &header));
228
229 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
230 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
231 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
232
Peter Boström5811a392015-12-10 13:02:50 +0100233 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700234
235 return SEND_PACKET;
236 }
237
stefanff483612015-12-21 03:14:00 -0800238 void ModifyVideoConfigs(
239 VideoSendStream::Config* send_config,
240 std::vector<VideoReceiveStream::Config>* receive_configs,
241 VideoEncoderConfig* encoder_config) override {
sprang867fb522015-08-03 04:38:41 -0700242 send_config->encoder_settings.encoder = &encoder_;
Stefan Holmer12952972015-10-29 15:13:24 +0100243 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700244 send_config->rtp.extensions.push_back(RtpExtension(
245 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
sprang867fb522015-08-03 04:38:41 -0700246 }
247
248 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100249 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700250 }
251
252 test::FakeEncoder encoder_;
253 } test;
254
stefane74eef12016-01-08 06:47:13 -0800255 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700256}
257
perkj803d97f2016-11-01 11:45:46 -0700258TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
259 class VideoRotationObserver : public test::SendTest {
260 public:
261 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
262 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
263 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
264 }
265
266 Action OnSendRtp(const uint8_t* packet, size_t length) override {
267 RTPHeader header;
268 EXPECT_TRUE(parser_->Parse(packet, length, &header));
269 EXPECT_TRUE(header.extension.hasVideoRotation);
270 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
271 observation_complete_.Set();
272 return SEND_PACKET;
273 }
274
275 void ModifyVideoConfigs(
276 VideoSendStream::Config* send_config,
277 std::vector<VideoReceiveStream::Config>* receive_configs,
278 VideoEncoderConfig* encoder_config) override {
279 send_config->rtp.extensions.clear();
280 send_config->rtp.extensions.push_back(RtpExtension(
281 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
282 }
283
284 void OnFrameGeneratorCapturerCreated(
285 test::FrameGeneratorCapturer* frame_generator_capturer) override {
286 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
287 }
288
289 void PerformTest() override {
290 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
291 }
292 } test;
293
294 RunBaseTest(&test);
295}
296
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000297class FakeReceiveStatistics : public NullReceiveStatistics {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000298 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000299 FakeReceiveStatistics(uint32_t send_ssrc,
300 uint32_t last_sequence_number,
301 uint32_t cumulative_lost,
302 uint8_t fraction_lost)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000303 : lossy_stats_(new LossyStatistician(last_sequence_number,
304 cumulative_lost,
305 fraction_lost)) {
306 stats_map_[send_ssrc] = lossy_stats_.get();
307 }
308
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000309 StatisticianMap GetActiveStatisticians() const override { return stats_map_; }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000310
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000311 StreamStatistician* GetStatistician(uint32_t ssrc) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000312 return lossy_stats_.get();
313 }
314
315 private:
316 class LossyStatistician : public StreamStatistician {
317 public:
318 LossyStatistician(uint32_t extended_max_sequence_number,
319 uint32_t cumulative_lost,
320 uint8_t fraction_lost) {
321 stats_.fraction_lost = fraction_lost;
322 stats_.cumulative_lost = cumulative_lost;
323 stats_.extended_max_sequence_number = extended_max_sequence_number;
324 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000325 bool GetStatistics(RtcpStatistics* statistics, bool reset) override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000326 *statistics = stats_;
327 return true;
328 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000329 void GetDataCounters(size_t* bytes_received,
330 uint32_t* packets_received) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000331 *bytes_received = 0;
332 *packets_received = 0;
333 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000334 void GetReceiveStreamDataCounters(
335 StreamDataCounters* data_counters) const override {}
336 uint32_t BitrateReceived() const override { return 0; }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000337 bool IsRetransmitOfOldPacket(const RTPHeader& header,
338 int64_t min_rtt) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000339 return false;
340 }
341
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000342 bool IsPacketInOrder(uint16_t sequence_number) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000343 return true;
344 }
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000345
346 RtcpStatistics stats_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000347 };
348
kwiberg27f982b2016-03-01 11:52:33 -0800349 std::unique_ptr<LossyStatistician> lossy_stats_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000350 StatisticianMap stats_map_;
351};
352
brandtre602f0a2016-10-31 03:40:49 -0700353class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100354 public:
brandtre602f0a2016-10-31 03:40:49 -0700355 UlpfecObserver(bool header_extensions_enabled,
Peter Boström39593972016-02-15 11:27:15 +0100356 bool use_nack,
357 bool expect_red,
brandtre602f0a2016-10-31 03:40:49 -0700358 bool expect_ulpfec,
Peter Boström39593972016-02-15 11:27:15 +0100359 const std::string& codec)
360 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
361 payload_name_(codec),
362 use_nack_(use_nack),
363 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700364 expect_ulpfec_(expect_ulpfec),
Stefan Holmer4654d202015-12-08 09:10:43 +0100365 send_count_(0),
366 received_media_(false),
367 received_fec_(false),
Peter Boström39593972016-02-15 11:27:15 +0100368 header_extensions_enabled_(header_extensions_enabled) {
369 if (codec == "H264") {
370 encoder_.reset(new test::FakeH264Encoder(Clock::GetRealTimeClock()));
371 } else if (codec == "VP8") {
magjed509e4fe2016-11-18 01:34:11 -0800372 encoder_.reset(VP8Encoder::Create());
Peter Boström39593972016-02-15 11:27:15 +0100373 } else if (codec == "VP9") {
magjed509e4fe2016-11-18 01:34:11 -0800374 encoder_.reset(VP9Encoder::Create());
Peter Boström39593972016-02-15 11:27:15 +0100375 } else {
376 RTC_NOTREACHED();
377 }
378 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100379
380 private:
381 Action OnSendRtp(const uint8_t* packet, size_t length) override {
382 RTPHeader header;
383 EXPECT_TRUE(parser_->Parse(packet, length, &header));
384
Peter Boström39593972016-02-15 11:27:15 +0100385 ++send_count_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100386 int encapsulated_payload_type = -1;
387 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100388 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100389 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
390 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100391 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100392 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
393 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100394 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100395 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100396 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
397 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100398 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
399 length) {
400 // Not padding-only, media received outside of RED.
401 EXPECT_FALSE(expect_red_);
402 received_media_ = true;
403 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100404 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000405
Stefan Holmer4654d202015-12-08 09:10:43 +0100406 if (header_extensions_enabled_) {
407 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
408 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
409 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
410 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
411 // 24 bits wrap.
412 EXPECT_GT(prev_header_.extension.absoluteSendTime,
413 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000414 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100415 EXPECT_GE(header.extension.absoluteSendTime,
416 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200417 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100418 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
419 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
420 prev_header_.extension.transportSequenceNumber;
421 EXPECT_EQ(1, seq_num_diff);
422 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200423
Stefan Holmer4654d202015-12-08 09:10:43 +0100424 if (encapsulated_payload_type != -1) {
425 if (encapsulated_payload_type ==
426 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700427 EXPECT_TRUE(expect_ulpfec_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100428 received_fec_ = true;
429 } else {
430 received_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000431 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000432 }
433
Peter Boström39593972016-02-15 11:27:15 +0100434 if (send_count_ > 100 && received_media_) {
brandtre602f0a2016-10-31 03:40:49 -0700435 if (received_fec_ || !expect_ulpfec_)
Peter Boström39593972016-02-15 11:27:15 +0100436 observation_complete_.Set();
437 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000438
Stefan Holmer4654d202015-12-08 09:10:43 +0100439 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000440
Stefan Holmer4654d202015-12-08 09:10:43 +0100441 return SEND_PACKET;
442 }
443
Peter Boström39593972016-02-15 11:27:15 +0100444 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
445 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
446 // Configure some network delay.
447 const int kNetworkDelayMs = 100;
448 FakeNetworkPipe::Config config;
449 config.loss_percent = 50;
450 config.queue_delay_ms = kNetworkDelayMs;
451 return new test::PacketTransport(sender_call, this,
452 test::PacketTransport::kSender, config);
453 }
454
stefanff483612015-12-21 03:14:00 -0800455 void ModifyVideoConfigs(
456 VideoSendStream::Config* send_config,
457 std::vector<VideoReceiveStream::Config>* receive_configs,
458 VideoEncoderConfig* encoder_config) override {
Stefan Holmer4654d202015-12-08 09:10:43 +0100459 transport_adapter_.reset(
460 new internal::TransportAdapter(send_config->send_transport));
461 transport_adapter_->Enable();
Peter Boström39593972016-02-15 11:27:15 +0100462 if (use_nack_) {
463 send_config->rtp.nack.rtp_history_ms =
464 (*receive_configs)[0].rtp.nack.rtp_history_ms =
465 VideoSendStreamTest::kNackRtpHistoryMs;
466 }
467 send_config->encoder_settings.encoder = encoder_.get();
468 send_config->encoder_settings.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700469 send_config->rtp.ulpfec.red_payload_type =
470 VideoSendStreamTest::kRedPayloadType;
471 send_config->rtp.ulpfec.ulpfec_payload_type =
472 VideoSendStreamTest::kUlpfecPayloadType;
Stefan Holmer4654d202015-12-08 09:10:43 +0100473 if (header_extensions_enabled_) {
474 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700475 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100476 send_config->rtp.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700477 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
Stefan Holmer4654d202015-12-08 09:10:43 +0100478 test::kTransportSequenceNumberExtensionId));
479 }
brandtrb5f2c3f2016-10-04 23:28:39 -0700480 (*receive_configs)[0].rtp.ulpfec.red_payload_type =
481 send_config->rtp.ulpfec.red_payload_type;
482 (*receive_configs)[0].rtp.ulpfec.ulpfec_payload_type =
483 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100484 }
485
486 void PerformTest() override {
487 EXPECT_TRUE(Wait()) << "Timed out waiting for FEC and media packets.";
488 }
489
kwiberg27f982b2016-03-01 11:52:33 -0800490 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
491 std::unique_ptr<VideoEncoder> encoder_;
Peter Boström39593972016-02-15 11:27:15 +0100492 const std::string payload_name_;
493 const bool use_nack_;
494 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700495 const bool expect_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100496 int send_count_;
497 bool received_media_;
498 bool received_fec_;
499 bool header_extensions_enabled_;
500 RTPHeader prev_header_;
501};
502
brandtre602f0a2016-10-31 03:40:49 -0700503TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
504 UlpfecObserver test(true, false, true, true, "VP8");
stefane74eef12016-01-08 06:47:13 -0800505 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100506}
507
brandtre602f0a2016-10-31 03:40:49 -0700508TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
509 UlpfecObserver test(false, false, true, true, "VP8");
Peter Boström39593972016-02-15 11:27:15 +0100510 RunBaseTest(&test);
511}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000512
Peter Boström39593972016-02-15 11:27:15 +0100513// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
514// since we'll still have to re-request FEC packets, effectively wasting
515// bandwidth since the receiver has to wait for FEC retransmissions to determine
516// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700517TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
518 UlpfecObserver test(false, true, true, false, "H264");
Peter Boström39593972016-02-15 11:27:15 +0100519 RunBaseTest(&test);
520}
521
522// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800523TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
brandtre602f0a2016-10-31 03:40:49 -0700524 UlpfecObserver test(false, false, true, true, "H264");
Peter Boström39593972016-02-15 11:27:15 +0100525 RunBaseTest(&test);
526}
527
brandtre6f98c72016-11-11 03:28:30 -0800528TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForVp8WithNackEnabled) {
brandtre602f0a2016-10-31 03:40:49 -0700529 UlpfecObserver test(false, true, true, true, "VP8");
Peter Boström39593972016-02-15 11:27:15 +0100530 RunBaseTest(&test);
531}
532
Peter Boström12996152016-05-14 02:03:18 +0200533#if !defined(RTC_DISABLE_VP9)
brandtre6f98c72016-11-11 03:28:30 -0800534TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForVp9WithNackEnabled) {
brandtre602f0a2016-10-31 03:40:49 -0700535 UlpfecObserver test(false, true, true, true, "VP9");
stefane74eef12016-01-08 06:47:13 -0800536 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000537}
Peter Boström12996152016-05-14 02:03:18 +0200538#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000539
brandtr39f97292016-11-16 22:57:50 -0800540// TODO(brandtr): Move these FlexFEC tests when we have created
541// FlexfecSendStream.
542class FlexfecObserver : public test::EndToEndTest {
543 public:
544 FlexfecObserver(bool header_extensions_enabled,
545 bool use_nack,
546 const std::string& codec)
547 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
548 payload_name_(codec),
549 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800550 sent_media_(false),
551 sent_flexfec_(false),
552 header_extensions_enabled_(header_extensions_enabled) {
553 if (codec == "H264") {
554 encoder_.reset(new test::FakeH264Encoder(Clock::GetRealTimeClock()));
555 } else if (codec == "VP8") {
magjed509e4fe2016-11-18 01:34:11 -0800556 encoder_.reset(VP8Encoder::Create());
brandtr39f97292016-11-16 22:57:50 -0800557 } else if (codec == "VP9") {
magjed509e4fe2016-11-18 01:34:11 -0800558 encoder_.reset(VP9Encoder::Create());
brandtr39f97292016-11-16 22:57:50 -0800559 } else {
560 RTC_NOTREACHED();
561 }
562 }
563
564 size_t GetNumFlexfecStreams() const override { return 1; }
565
566 private:
567 Action OnSendRtp(const uint8_t* packet, size_t length) override {
568 RTPHeader header;
569 EXPECT_TRUE(parser_->Parse(packet, length, &header));
570
brandtr39f97292016-11-16 22:57:50 -0800571 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
572 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
573 sent_flexfec_ = true;
574 } else {
575 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
576 header.payloadType);
577 EXPECT_EQ(VideoSendStreamTest::kVideoSendSsrcs[0], header.ssrc);
578 sent_media_ = true;
579 }
580
581 if (header_extensions_enabled_) {
582 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
583 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
584 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
585 }
586
brandtr0c5a1542016-11-23 04:42:26 -0800587 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800588 observation_complete_.Set();
589 }
590
591 return SEND_PACKET;
592 }
593
594 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
595 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
596 // Therefore we need some network delay.
597 const int kNetworkDelayMs = 100;
598 FakeNetworkPipe::Config config;
brandtrd654a9b2016-12-05 05:38:19 -0800599 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800600 config.queue_delay_ms = kNetworkDelayMs;
601 return new test::PacketTransport(sender_call, this,
602 test::PacketTransport::kSender, config);
603 }
604
605 void ModifyVideoConfigs(
606 VideoSendStream::Config* send_config,
607 std::vector<VideoReceiveStream::Config>* receive_configs,
608 VideoEncoderConfig* encoder_config) override {
609 transport_adapter_.reset(
610 new internal::TransportAdapter(send_config->send_transport));
611 transport_adapter_->Enable();
612 if (use_nack_) {
613 send_config->rtp.nack.rtp_history_ms =
614 (*receive_configs)[0].rtp.nack.rtp_history_ms =
615 VideoSendStreamTest::kNackRtpHistoryMs;
616 }
617 send_config->encoder_settings.encoder = encoder_.get();
618 send_config->encoder_settings.payload_name = payload_name_;
619 if (header_extensions_enabled_) {
620 send_config->rtp.extensions.push_back(RtpExtension(
621 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
622 send_config->rtp.extensions.push_back(RtpExtension(
623 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
624 send_config->rtp.extensions.push_back(
625 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
626 test::kTransportSequenceNumberExtensionId));
627 }
628 }
629
630 void PerformTest() override {
631 EXPECT_TRUE(Wait())
632 << "Timed out waiting for FlexFEC and/or media packets.";
633 }
634
635 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
636 std::unique_ptr<VideoEncoder> encoder_;
637 const std::string payload_name_;
638 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800639 bool sent_media_;
640 bool sent_flexfec_;
641 bool header_extensions_enabled_;
642};
643
brandtrd654a9b2016-12-05 05:38:19 -0800644TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
645 FlexfecObserver test(false, false, "VP8");
646 RunBaseTest(&test);
647}
648
649TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
650 FlexfecObserver test(false, true, "VP8");
651 RunBaseTest(&test);
652}
653
brandtr39f97292016-11-16 22:57:50 -0800654TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
655 FlexfecObserver test(true, false, "VP8");
656 RunBaseTest(&test);
657}
658
brandtr39f97292016-11-16 22:57:50 -0800659#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800660TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
brandtr39f97292016-11-16 22:57:50 -0800661 FlexfecObserver test(false, false, "VP9");
662 RunBaseTest(&test);
663}
664
brandtrd654a9b2016-12-05 05:38:19 -0800665TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
brandtr39f97292016-11-16 22:57:50 -0800666 FlexfecObserver test(false, true, "VP9");
667 RunBaseTest(&test);
668}
669#endif // defined(RTC_DISABLE_VP9)
670
brandtrd654a9b2016-12-05 05:38:19 -0800671TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
brandtr39f97292016-11-16 22:57:50 -0800672 FlexfecObserver test(false, false, "H264");
673 RunBaseTest(&test);
674}
675
brandtrd654a9b2016-12-05 05:38:19 -0800676TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
brandtr39f97292016-11-16 22:57:50 -0800677 FlexfecObserver test(false, true, "H264");
678 RunBaseTest(&test);
679}
680
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000681void VideoSendStreamTest::TestNackRetransmission(
682 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000683 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000684 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000685 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000686 explicit NackObserver(uint32_t retransmit_ssrc,
687 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000688 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000689 send_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000690 retransmit_ssrc_(retransmit_ssrc),
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000691 retransmit_payload_type_(retransmit_payload_type),
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000692 nacked_sequence_number_(-1) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000693 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000694
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000695 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000696 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000697 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000698 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000699
700 // Nack second packet after receiving the third one.
701 if (++send_count_ == 3) {
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000702 uint16_t nack_sequence_number = header.sequenceNumber - 1;
703 nacked_sequence_number_ = nack_sequence_number;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000704 NullReceiveStatistics null_stats;
Peter Boströmac547a62015-09-17 23:03:57 +0200705 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), &null_stats,
terelius429c3452016-01-21 05:42:04 -0800706 nullptr, nullptr, transport_adapter_.get());
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000707
pbosda903ea2015-10-02 02:36:56 -0700708 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100709 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000710
711 RTCPSender::FeedbackState feedback_state;
712
713 EXPECT_EQ(0,
714 rtcp_sender.SendRTCP(
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000715 feedback_state, kRtcpNack, 1, &nack_sequence_number));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000716 }
717
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000718 uint16_t sequence_number = header.sequenceNumber;
719
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000720 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100721 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
722 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000723 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000724 const uint8_t* rtx_header = packet + header.headerLength;
725 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
726 }
727
728 if (sequence_number == nacked_sequence_number_) {
729 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000730 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
Peter Boström5811a392015-12-10 13:02:50 +0100731 observation_complete_.Set();
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000732 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000733
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000734 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000735 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000736
stefanff483612015-12-21 03:14:00 -0800737 void ModifyVideoConfigs(
738 VideoSendStream::Config* send_config,
739 std::vector<VideoReceiveStream::Config>* receive_configs,
740 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700741 transport_adapter_.reset(
742 new internal::TransportAdapter(send_config->send_transport));
743 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000744 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000745 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100746 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000747 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
748 }
749
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000750 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100751 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000752 }
753
kwiberg27f982b2016-03-01 11:52:33 -0800754 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000755 int send_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000756 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000757 uint8_t retransmit_payload_type_;
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000758 int nacked_sequence_number_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000759 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000760
stefane74eef12016-01-08 06:47:13 -0800761 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000762}
763
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000764TEST_F(VideoSendStreamTest, RetransmitsNack) {
765 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100766 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000767}
768
769TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
770 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000771 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000772}
773
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000774void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
775 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000776 // Use a fake encoder to output a frame of every size in the range [90, 290],
777 // for each size making sure that the exact number of payload bytes received
778 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000779 static const size_t kMaxPacketSize = 128;
780 static const size_t start = 90;
781 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000782
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000783 // Observer that verifies that the expected number of packets and bytes
784 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000785 class FrameFragmentationTest : public test::SendTest,
786 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000787 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000788 FrameFragmentationTest(size_t max_packet_size,
789 size_t start_size,
790 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000791 bool test_generic_packetization,
792 bool use_fec)
793 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000794 encoder_(stop),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000795 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000796 stop_size_(stop_size),
797 test_generic_packetization_(test_generic_packetization),
798 use_fec_(use_fec),
799 packet_count_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000800 accumulated_size_(0),
801 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000802 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000803 current_size_rtp_(start_size),
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000804 current_size_frame_(static_cast<int32_t>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000805 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000806 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700807 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000808 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000809
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000810 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000811 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000812 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000813 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000814 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000815
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000816 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000817
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000818 if (use_fec_) {
819 uint8_t payload_type = packet[header.headerLength];
820 bool is_fec = header.payloadType == kRedPayloadType &&
821 payload_type == kUlpfecPayloadType;
822 if (is_fec) {
823 fec_packet_received_ = true;
824 return SEND_PACKET;
825 }
826 }
827
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000828 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000829
830 if (use_fec_)
831 TriggerLossReport(header);
832
833 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200834 size_t overhead = header.headerLength + header.paddingLength;
835 // Only remove payload header and RED header if the packet actually
836 // contains payload.
837 if (length > overhead) {
838 overhead += (1 /* Generic header */);
839 if (use_fec_)
840 overhead += 1; // RED for FEC header.
841 }
842 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000843 accumulated_payload_ += length - overhead;
844 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000845
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000846 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000847 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000848 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
849 // With FEC enabled, frame size is incremented asynchronously, so
850 // "old" frames one byte too small may arrive. Accept, but don't
851 // increase expected frame size.
852 accumulated_size_ = 0;
853 accumulated_payload_ = 0;
854 return SEND_PACKET;
855 }
856
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000857 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000858 if (test_generic_packetization_) {
859 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
860 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000861
862 // Last packet of frame; reset counters.
863 accumulated_size_ = 0;
864 accumulated_payload_ = 0;
865 if (current_size_rtp_ == stop_size_) {
866 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +0100867 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000868 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000869 // Increase next expected frame size. If testing with FEC, make sure
870 // a FEC packet has been received for this frame size before
871 // proceeding, to make sure that redundancy packets don't exceed
872 // size limit.
873 if (!use_fec_) {
874 ++current_size_rtp_;
875 } else if (fec_packet_received_) {
876 fec_packet_received_ = false;
877 ++current_size_rtp_;
878 ++current_size_frame_;
879 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000880 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000881 }
882
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000883 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000884 }
885
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000886 void TriggerLossReport(const RTPHeader& header) {
887 // Send lossy receive reports to trigger FEC enabling.
888 if (packet_count_++ % 2 != 0) {
889 // Receive statistics reporting having lost 50% of the packets.
890 FakeReceiveStatistics lossy_receive_stats(
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100891 kVideoSendSsrcs[0], header.sequenceNumber, packet_count_ / 2, 127);
Peter Boströmac547a62015-09-17 23:03:57 +0200892 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -0800893 &lossy_receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -0700894 transport_adapter_.get());
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000895
pbosda903ea2015-10-02 02:36:56 -0700896 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100897 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000898
899 RTCPSender::FeedbackState feedback_state;
900
901 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
902 }
903 }
904
nisseef8b61e2016-04-29 06:09:15 -0700905 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000906 // Increase frame size for next encoded frame, in the context of the
907 // encoder thread.
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000908 if (!use_fec_ &&
909 current_size_frame_.Value() < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000910 ++current_size_frame_;
911 }
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000912 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_.Value()));
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000913 }
914
Stefan Holmere5904162015-03-26 11:11:06 +0100915 Call::Config GetSenderCallConfig() override {
skvlad11a9cbf2016-10-07 11:53:05 -0700916 Call::Config config(&event_log_);
Stefan Holmere5904162015-03-26 11:11:06 +0100917 const int kMinBitrateBps = 30000;
918 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
919 return config;
920 }
921
stefanff483612015-12-21 03:14:00 -0800922 void ModifyVideoConfigs(
923 VideoSendStream::Config* send_config,
924 std::vector<VideoReceiveStream::Config>* receive_configs,
925 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700926 transport_adapter_.reset(
927 new internal::TransportAdapter(send_config->send_transport));
928 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000929 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -0700930 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
931 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000932 }
933
934 if (!test_generic_packetization_)
935 send_config->encoder_settings.payload_name = "VP8";
936
937 send_config->encoder_settings.encoder = &encoder_;
938 send_config->rtp.max_packet_size = kMaxPacketSize;
939 send_config->post_encode_callback = this;
940
Erik Språng95261872015-04-10 11:58:49 +0200941 // Make sure there is at least one extension header, to make the RTP
942 // header larger than the base length of 12 bytes.
943 EXPECT_FALSE(send_config->rtp.extensions.empty());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000944 }
945
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000946 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100947 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000948 }
949
kwiberg27f982b2016-03-01 11:52:33 -0800950 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000951 test::ConfigurableFrameSizeEncoder encoder_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000952
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000953 const size_t max_packet_size_;
954 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000955 const bool test_generic_packetization_;
956 const bool use_fec_;
957
958 uint32_t packet_count_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000959 size_t accumulated_size_;
960 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000961 bool fec_packet_received_;
962
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000963 size_t current_size_rtp_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000964 Atomic32 current_size_frame_;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000965 };
966
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000967 // Don't auto increment if FEC is used; continue sending frame size until
968 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000969 FrameFragmentationTest test(
970 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000971
stefane74eef12016-01-08 06:47:13 -0800972 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000973}
974
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000975// TODO(sprang): Is there any way of speeding up these tests?
976TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
977 TestPacketFragmentationSize(kGeneric, false);
978}
979
980TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
981 TestPacketFragmentationSize(kGeneric, true);
982}
983
984TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
985 TestPacketFragmentationSize(kVP8, false);
986}
987
988TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
989 TestPacketFragmentationSize(kVP8, true);
990}
991
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000992// The test will go through a number of phases.
993// 1. Start sending packets.
994// 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 +0000995// suspend the stream.
996// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000997// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000998// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +0000999// When the stream is detected again, and the stats show that the stream
1000// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001001TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1002 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001003
nissed30a1112016-04-18 05:15:22 -07001004 class RembObserver : public test::SendTest,
1005 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001006 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001007 RembObserver()
1008 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001009 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001010 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001011 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001012 rtp_count_(0),
1013 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001014 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001015 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001016 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001017
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001018 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001019 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001020 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001021 ++rtp_count_;
1022 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001023 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001024 last_sequence_number_ = header.sequenceNumber;
1025
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001026 if (test_state_ == kBeforeSuspend) {
1027 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001028 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001029 test_state_ = kDuringSuspend;
1030 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001031 if (header.paddingLength == 0) {
1032 // Received non-padding packet during suspension period. Reset the
1033 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001034 suspended_frame_count_ = 0;
1035 }
stefanf116bd02015-10-27 08:29:42 -07001036 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001037 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001038 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001039 // Non-padding packet observed. Test is almost complete. Will just
1040 // have to wait for the stats to change.
1041 test_state_ = kWaitingForStats;
1042 }
stefanf116bd02015-10-27 08:29:42 -07001043 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001044 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001045 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001046 if (stats.suspended == false) {
1047 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001048 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001049 }
stefanf116bd02015-10-27 08:29:42 -07001050 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001051 }
1052
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001053 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001054 }
1055
perkj26091b12016-09-01 01:17:40 -07001056 // This method implements the rtc::VideoSinkInterface. This is called when
1057 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001058 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001059 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001060 if (test_state_ == kDuringSuspend &&
1061 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001062 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001063 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001064 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001065 test_state_ = kWaitingForPacket;
1066 }
1067 }
1068
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001069 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001070 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001071 low_remb_bps_ = value;
1072 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001073
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001074 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001075 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001076 high_remb_bps_ = value;
1077 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001078
stefanff483612015-12-21 03:14:00 -08001079 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001080 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001081 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001082 stream_ = send_stream;
1083 }
1084
stefanff483612015-12-21 03:14:00 -08001085 void ModifyVideoConfigs(
1086 VideoSendStream::Config* send_config,
1087 std::vector<VideoReceiveStream::Config>* receive_configs,
1088 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001089 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001090 transport_adapter_.reset(
1091 new internal::TransportAdapter(send_config->send_transport));
1092 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001093 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001094 send_config->pre_encode_callback = this;
1095 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001096 int min_bitrate_bps =
1097 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001098 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001099 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001100 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001101 min_bitrate_bps + threshold_window + 5000);
1102 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1103 }
1104
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001105 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001106 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001107 }
1108
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001109 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001110 kBeforeSuspend,
1111 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001112 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001113 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001114 };
1115
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001116 virtual void SendRtcpFeedback(int remb_value)
1117 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001118 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1119 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001120 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -07001121 transport_adapter_.get());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001122
pbosda903ea2015-10-02 02:36:56 -07001123 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001124 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001125 if (remb_value > 0) {
1126 rtcp_sender.SetREMBStatus(true);
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001127 rtcp_sender.SetREMBData(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001128 }
1129 RTCPSender::FeedbackState feedback_state;
1130 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1131 }
1132
kwiberg27f982b2016-03-01 11:52:33 -08001133 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001134 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001135 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001136
Peter Boströmf2f82832015-05-01 13:00:41 +02001137 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001138 TestState test_state_ GUARDED_BY(crit_);
1139 int rtp_count_ GUARDED_BY(crit_);
1140 int last_sequence_number_ GUARDED_BY(crit_);
1141 int suspended_frame_count_ GUARDED_BY(crit_);
1142 int low_remb_bps_ GUARDED_BY(crit_);
1143 int high_remb_bps_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001144 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001145
stefane74eef12016-01-08 06:47:13 -08001146 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001147}
1148
perkj71ee44c2016-06-15 00:47:53 -07001149// This test that padding stops being send after a while if the Camera stops
1150// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001151TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001152 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001153 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001154 NoPaddingWhenVideoIsMuted()
1155 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001156 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001157 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001158 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +00001159 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001160
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001161 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001162 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001163 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001164 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001165
1166 RTPHeader header;
1167 parser_->Parse(packet, length, &header);
1168 const bool only_padding =
1169 header.headerLength + header.paddingLength == length;
1170
1171 if (test_state_ == kBeforeStopCapture) {
1172 capturer_->Stop();
1173 test_state_ = kWaitingForPadding;
1174 } else if (test_state_ == kWaitingForPadding && only_padding) {
1175 test_state_ = kWaitingForNoPackets;
1176 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1177 only_padding) {
1178 observation_complete_.Set();
1179 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001180 return SEND_PACKET;
1181 }
1182
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001183 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001184 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001185 const int kNoPacketsThresholdMs = 2000;
1186 if (test_state_ == kWaitingForNoPackets &&
1187 (last_packet_time_ms_ > 0 &&
1188 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1189 kNoPacketsThresholdMs)) {
1190 capturer_->Start();
1191 test_state_ = kWaitingForPaddingAfterCameraRestart;
1192 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001193 return SEND_PACKET;
1194 }
1195
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001196 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001197
nisseef8b61e2016-04-29 06:09:15 -07001198 void OnFrameGeneratorCapturerCreated(
1199 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001200 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001201 capturer_ = frame_generator_capturer;
1202 }
1203
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001204 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001205 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001206 << "Timed out while waiting for RTP packets to stop being sent.";
1207 }
1208
perkj71ee44c2016-06-15 00:47:53 -07001209 enum TestState {
1210 kBeforeStopCapture,
1211 kWaitingForPadding,
1212 kWaitingForNoPackets,
1213 kWaitingForPaddingAfterCameraRestart
1214 };
1215
1216 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001217 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001218 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001219 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001220 int64_t last_packet_time_ms_ GUARDED_BY(crit_);
1221 test::FrameGeneratorCapturer* capturer_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001222 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001223
stefane74eef12016-01-08 06:47:13 -08001224 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001225}
1226
isheriffcc5903e2016-10-04 08:29:38 -07001227TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1228 const int kCapacityKbps = 10000; // 10 Mbps
1229 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1230 public:
1231 PaddingIsPrimarilyRetransmissions()
1232 : EndToEndTest(kDefaultTimeoutMs),
1233 clock_(Clock::GetRealTimeClock()),
1234 padding_length_(0),
1235 total_length_(0),
1236 call_(nullptr) {}
1237
1238 private:
1239 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1240 call_ = sender_call;
1241 }
1242
1243 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1244 rtc::CritScope lock(&crit_);
1245
1246 RTPHeader header;
1247 parser_->Parse(packet, length, &header);
1248 padding_length_ += header.paddingLength;
1249 total_length_ += length;
1250 return SEND_PACKET;
1251 }
1252
1253 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
1254 const int kNetworkDelayMs = 50;
1255 FakeNetworkPipe::Config config;
1256 config.loss_percent = 10;
1257 config.link_capacity_kbps = kCapacityKbps;
1258 config.queue_delay_ms = kNetworkDelayMs;
1259 return new test::PacketTransport(sender_call, this,
1260 test::PacketTransport::kSender, config);
1261 }
1262
1263 void ModifyVideoConfigs(
1264 VideoSendStream::Config* send_config,
1265 std::vector<VideoReceiveStream::Config>* receive_configs,
1266 VideoEncoderConfig* encoder_config) override {
1267 send_config->rtp.extensions.clear();
1268 send_config->rtp.extensions.push_back(
1269 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
1270 test::kTransportSequenceNumberExtensionId));
1271 // Turn on RTX.
1272 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1273 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
1274
1275 (*receive_configs)[0].rtp.extensions.clear();
1276 (*receive_configs)[0].rtp.extensions.push_back(
1277 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
1278 test::kTransportSequenceNumberExtensionId));
1279 (*receive_configs)[0].rtp.transport_cc = true;
1280 }
1281
1282 void PerformTest() override {
1283 // TODO(isheriff): Some platforms do not ramp up as expected to full
1284 // capacity due to packet scheduling delays. Fix that before getting
1285 // rid of this.
1286 SleepMs(5000);
1287 {
1288 rtc::CritScope lock(&crit_);
1289 // Expect padding to be a small percentage of total bytes sent.
1290 EXPECT_LT(padding_length_, .1 * total_length_);
1291 }
1292 }
1293
1294 rtc::CriticalSection crit_;
1295 Clock* const clock_;
1296 size_t padding_length_ GUARDED_BY(crit_);
1297 size_t total_length_ GUARDED_BY(crit_);
1298 Call* call_;
1299 } test;
1300
1301 RunBaseTest(&test);
1302}
1303
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001304// This test first observes "high" bitrate use at which point it sends a REMB to
1305// indicate that it should be lowered significantly. The test then observes that
1306// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1307// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001308//
1309// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1310// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001311TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1312 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001313 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001314 static const int kRembBitrateBps = 80000;
1315 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001316 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001317 public:
1318 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001319 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001320 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1321 stream_(nullptr),
1322 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001323
1324 private:
nisseef8b61e2016-04-29 06:09:15 -07001325 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001326 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001327 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001328
1329 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001330 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001331 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001332 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001333 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001334 if (!stats.substreams.empty()) {
1335 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001336 int total_bitrate_bps =
1337 stats.substreams.begin()->second.total_bitrate_bps;
1338 test::PrintResult("bitrate_stats_",
1339 "min_transmit_bitrate_low_remb",
1340 "bitrate_bps",
1341 static_cast<size_t>(total_bitrate_bps),
1342 "bps",
1343 false);
1344 if (total_bitrate_bps > kHighBitrateBps) {
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001345 rtp_rtcp_->SetREMBData(kRembBitrateBps,
1346 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001347 rtp_rtcp_->Process();
1348 bitrate_capped_ = true;
1349 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001350 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001351 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001352 }
1353 }
stefanf116bd02015-10-27 08:29:42 -07001354 // Packets don't have to be delivered since the test is the receiver.
1355 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001356 }
1357
stefanff483612015-12-21 03:14:00 -08001358 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001359 VideoSendStream* send_stream,
1360 const std::vector<VideoReceiveStream*>& receive_streams) override {
1361 stream_ = send_stream;
1362 RtpRtcp::Configuration config;
1363 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001364 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001365 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
1366 rtp_rtcp_->SetREMBStatus(true);
1367 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001368 }
1369
stefanff483612015-12-21 03:14:00 -08001370 void ModifyVideoConfigs(
1371 VideoSendStream::Config* send_config,
1372 std::vector<VideoReceiveStream::Config>* receive_configs,
1373 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001374 feedback_transport_.reset(
1375 new internal::TransportAdapter(send_config->send_transport));
1376 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001377 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001378 }
1379
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001380 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001381 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001382 << "Timeout while waiting for low bitrate stats after REMB.";
1383 }
1384
kwiberg27f982b2016-03-01 11:52:33 -08001385 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1386 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001387 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001388 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001389 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001390 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001391
stefane74eef12016-01-08 06:47:13 -08001392 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001393}
1394
Stefan Holmer280de9e2016-09-30 10:06:51 +02001395TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1396 static const int kStartBitrateBps = 300000;
1397 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001398 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001399 class ChangingNetworkRouteTest : public test::EndToEndTest {
1400 public:
Stefan Holmerbe402962016-07-08 16:16:41 +02001401 ChangingNetworkRouteTest()
Stefan Holmer280de9e2016-09-30 10:06:51 +02001402 : EndToEndTest(test::CallTest::kDefaultTimeoutMs), call_(nullptr) {
1403 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1404 kRtpExtensionTransportSequenceNumber, kExtensionId));
1405 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001406
1407 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1408 call_ = sender_call;
1409 }
1410
Stefan Holmer280de9e2016-09-30 10:06:51 +02001411 void ModifyVideoConfigs(
1412 VideoSendStream::Config* send_config,
1413 std::vector<VideoReceiveStream::Config>* receive_configs,
1414 VideoEncoderConfig* encoder_config) override {
1415 send_config->rtp.extensions.clear();
1416 send_config->rtp.extensions.push_back(RtpExtension(
1417 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1418 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1419 (*receive_configs)[0].rtp.transport_cc = true;
1420 }
1421
1422 void ModifyAudioConfigs(
1423 AudioSendStream::Config* send_config,
1424 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1425 send_config->rtp.extensions.clear();
1426 send_config->rtp.extensions.push_back(RtpExtension(
1427 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1428 (*receive_configs)[0].rtp.extensions.clear();
1429 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1430 (*receive_configs)[0].rtp.transport_cc = true;
1431 }
1432
Stefan Holmerbe402962016-07-08 16:16:41 +02001433 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1434 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1435 observation_complete_.Set();
1436 }
1437
1438 return SEND_PACKET;
1439 }
1440
1441 void PerformTest() override {
1442 rtc::NetworkRoute new_route(true, 10, 20, -1);
1443 call_->OnNetworkRouteChanged("transport", new_route);
1444 Call::Config::BitrateConfig bitrate_config;
1445 bitrate_config.start_bitrate_bps = kStartBitrateBps;
1446 call_->SetBitrateConfig(bitrate_config);
1447 EXPECT_TRUE(Wait())
1448 << "Timed out while waiting for start bitrate to be exceeded.";
1449
1450 bitrate_config.start_bitrate_bps = -1;
1451 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
1452 call_->SetBitrateConfig(bitrate_config);
1453 // TODO(holmer): We should set the last sent packet id here and verify
1454 // that we correctly ignore any packet loss reported prior to that id.
1455 ++new_route.local_network_id;
1456 call_->OnNetworkRouteChanged("transport", new_route);
stefan01bbc3c2016-10-25 04:19:48 -07001457 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
Stefan Holmerbe402962016-07-08 16:16:41 +02001458 }
1459
1460 private:
1461 Call* call_;
1462 } test;
1463
1464 RunBaseTest(&test);
1465}
1466
michaelt79e05882016-11-08 02:50:09 -08001467TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
1468 class ChangingTransportOverheadTest : public test::EndToEndTest {
1469 public:
1470 ChangingTransportOverheadTest()
1471 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1472 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001473 packets_sent_(0),
1474 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001475
1476 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1477 call_ = sender_call;
1478 }
1479
1480 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001481 EXPECT_LE(length, kMaxRtpPacketSize);
michaelt79e05882016-11-08 02:50:09 -08001482 if (++packets_sent_ < 100)
1483 return SEND_PACKET;
1484 observation_complete_.Set();
1485 return SEND_PACKET;
1486 }
1487
michaelta3328772016-11-29 09:25:03 -08001488 void ModifyVideoConfigs(
1489 VideoSendStream::Config* send_config,
1490 std::vector<VideoReceiveStream::Config>* receive_configs,
1491 VideoEncoderConfig* encoder_config) override {
1492 send_config->rtp.max_packet_size = kMaxRtpPacketSize;
1493 }
1494
michaelt79e05882016-11-08 02:50:09 -08001495 void PerformTest() override {
michaelta3328772016-11-29 09:25:03 -08001496 transport_overhead_ = 100;
michaelt79e05882016-11-08 02:50:09 -08001497 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1498 transport_overhead_);
1499 EXPECT_TRUE(Wait());
1500 packets_sent_ = 0;
michaelta3328772016-11-29 09:25:03 -08001501 transport_overhead_ = 500;
michaelt79e05882016-11-08 02:50:09 -08001502 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1503 transport_overhead_);
1504 EXPECT_TRUE(Wait());
1505 }
1506
1507 private:
1508 Call* call_;
1509 int packets_sent_;
1510 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001511 const size_t kMaxRtpPacketSize = 1000;
michaelt79e05882016-11-08 02:50:09 -08001512 } test;
1513
1514 RunBaseTest(&test);
1515}
1516
sprang9c0b5512016-07-06 00:54:28 -07001517class MaxPaddingSetTest : public test::SendTest {
1518 public:
1519 static const uint32_t kMinTransmitBitrateBps = 400000;
1520 static const uint32_t kActualEncodeBitrateBps = 40000;
1521 static const uint32_t kMinPacketsToSend = 50;
1522
1523 explicit MaxPaddingSetTest(bool test_switch_content_type)
1524 : SendTest(test::CallTest::kDefaultTimeoutMs),
1525 call_(nullptr),
1526 send_stream_(nullptr),
1527 packets_sent_(0),
1528 running_without_padding_(test_switch_content_type) {}
1529
1530 void OnVideoStreamsCreated(
1531 VideoSendStream* send_stream,
1532 const std::vector<VideoReceiveStream*>& receive_streams) override {
1533 send_stream_ = send_stream;
1534 }
1535
1536 void ModifyVideoConfigs(
1537 VideoSendStream::Config* send_config,
1538 std::vector<VideoReceiveStream::Config>* receive_configs,
1539 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001540 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprang9c0b5512016-07-06 00:54:28 -07001541 if (running_without_padding_) {
1542 encoder_config->min_transmit_bitrate_bps = 0;
1543 encoder_config->content_type =
1544 VideoEncoderConfig::ContentType::kRealtimeVideo;
1545 } else {
1546 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1547 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1548 }
perkj26091b12016-09-01 01:17:40 -07001549 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001550 }
1551
1552 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1553 call_ = sender_call;
1554 }
1555
1556 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1557 rtc::CritScope lock(&crit_);
1558
1559 if (running_without_padding_)
1560 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1561
1562 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1563 // we have reliable data.
1564 if (++packets_sent_ < kMinPacketsToSend)
1565 return SEND_PACKET;
1566
1567 if (running_without_padding_) {
1568 // We've sent kMinPacketsToSend packets with default configuration, switch
1569 // to enabling screen content and setting min transmit bitrate.
1570 packets_sent_ = 0;
1571 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1572 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
perkj26091b12016-09-01 01:17:40 -07001573 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
sprang9c0b5512016-07-06 00:54:28 -07001574 running_without_padding_ = false;
1575 return SEND_PACKET;
1576 }
1577
1578 // Make sure the pacer has been configured with a min transmit bitrate.
1579 if (call_->GetStats().max_padding_bitrate_bps > 0)
1580 observation_complete_.Set();
1581
1582 return SEND_PACKET;
1583 }
1584
1585 void PerformTest() override {
1586 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1587 }
1588
1589 private:
1590 rtc::CriticalSection crit_;
1591 Call* call_;
1592 VideoSendStream* send_stream_;
1593 VideoEncoderConfig encoder_config_;
1594 uint32_t packets_sent_ GUARDED_BY(crit_);
1595 bool running_without_padding_;
1596};
1597
1598TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
1599 MaxPaddingSetTest test(false);
1600 RunBaseTest(&test);
1601}
1602
1603TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
1604 MaxPaddingSetTest test(true);
1605 RunBaseTest(&test);
1606}
1607
perkjfa10b552016-10-02 23:45:26 -07001608// This test verifies that new frame sizes reconfigures encoders even though not
1609// (yet) sending. The purpose of this is to permit encoding as quickly as
1610// possible once we start sending. Likely the frames being input are from the
1611// same source that will be sent later, which just means that we're ready
1612// earlier.
1613TEST_F(VideoSendStreamTest,
1614 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1615 class EncoderObserver : public test::FakeEncoder {
1616 public:
1617 EncoderObserver()
1618 : FakeEncoder(Clock::GetRealTimeClock()),
1619 init_encode_called_(false, false),
1620 number_of_initializations_(0),
1621 last_initialized_frame_width_(0),
1622 last_initialized_frame_height_(0) {}
1623
1624 void WaitForResolution(int width, int height) {
1625 {
1626 rtc::CritScope lock(&crit_);
1627 if (last_initialized_frame_width_ == width &&
1628 last_initialized_frame_height_ == height) {
1629 return;
1630 }
1631 }
Erik Språng08127a92016-11-16 16:41:30 +01001632 EXPECT_TRUE(
1633 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001634 {
1635 rtc::CritScope lock(&crit_);
1636 EXPECT_EQ(width, last_initialized_frame_width_);
1637 EXPECT_EQ(height, last_initialized_frame_height_);
1638 }
1639 }
1640
1641 private:
1642 int32_t InitEncode(const VideoCodec* config,
1643 int32_t number_of_cores,
1644 size_t max_payload_size) override {
1645 rtc::CritScope lock(&crit_);
1646 last_initialized_frame_width_ = config->width;
1647 last_initialized_frame_height_ = config->height;
1648 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001649 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001650 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1651 }
1652
1653 int32_t Encode(const VideoFrame& input_image,
1654 const CodecSpecificInfo* codec_specific_info,
1655 const std::vector<FrameType>* frame_types) override {
1656 ADD_FAILURE()
1657 << "Unexpected Encode call since the send stream is not started";
1658 return 0;
1659 }
1660
1661 rtc::CriticalSection crit_;
1662 rtc::Event init_encode_called_;
1663 size_t number_of_initializations_ GUARDED_BY(&crit_);
1664 int last_initialized_frame_width_ GUARDED_BY(&crit_);
1665 int last_initialized_frame_height_ GUARDED_BY(&crit_);
1666 };
1667
skvlad11a9cbf2016-10-07 11:53:05 -07001668 CreateSenderCall(Call::Config(&event_log_));
perkjfa10b552016-10-02 23:45:26 -07001669 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001670 CreateSendConfig(1, 0, 0, &transport);
perkjfa10b552016-10-02 23:45:26 -07001671 EncoderObserver encoder;
1672 video_send_config_.encoder_settings.encoder = &encoder;
1673 CreateVideoStreams();
1674 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1675 kDefaultHeight);
1676 frame_generator_capturer_->Start();
1677
1678 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
1679 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1680 kDefaultHeight * 2);
1681 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
1682 DestroyStreams();
1683}
1684
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001685TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1686 class StartBitrateObserver : public test::FakeEncoder {
1687 public:
1688 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001689 : FakeEncoder(Clock::GetRealTimeClock()),
1690 start_bitrate_changed_(false, false),
1691 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001692 int32_t InitEncode(const VideoCodec* config,
1693 int32_t number_of_cores,
1694 size_t max_payload_size) override {
1695 rtc::CritScope lock(&crit_);
1696 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001697 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001698 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1699 }
1700
1701 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1702 rtc::CritScope lock(&crit_);
1703 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001704 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001705 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1706 }
1707
1708 int GetStartBitrateKbps() const {
1709 rtc::CritScope lock(&crit_);
1710 return start_bitrate_kbps_;
1711 }
1712
pbos14fe7082016-04-20 06:35:56 -07001713 bool WaitForStartBitrate() {
1714 return start_bitrate_changed_.Wait(
1715 VideoSendStreamTest::kDefaultTimeoutMs);
1716 }
1717
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001718 private:
pbos5ad935c2016-01-25 03:52:44 -08001719 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001720 rtc::Event start_bitrate_changed_;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001721 int start_bitrate_kbps_ GUARDED_BY(crit_);
1722 };
1723
skvlad11a9cbf2016-10-07 11:53:05 -07001724 CreateSenderCall(Call::Config(&event_log_));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001725
solenberg4fbae2b2015-08-28 04:07:10 -07001726 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001727 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001728
1729 Call::Config::BitrateConfig bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07001730 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001731 sender_call_->SetBitrateConfig(bitrate_config);
1732
1733 StartBitrateObserver encoder;
stefanff483612015-12-21 03:14:00 -08001734 video_send_config_.encoder_settings.encoder = &encoder;
perkjfa10b552016-10-02 23:45:26 -07001735 // Since this test does not use a capturer, set |internal_source| = true.
1736 // Encoder configuration is otherwise updated on the next video frame.
1737 video_send_config_.encoder_settings.internal_source = true;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001738
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001739 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001740
pbos14fe7082016-04-20 06:35:56 -07001741 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07001742 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001743 encoder.GetStartBitrateKbps());
1744
perkjfa10b552016-10-02 23:45:26 -07001745 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07001746 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001747
1748 // New bitrate should be reconfigured above the previous max. As there's no
1749 // network connection this shouldn't be flaky, as no bitrate should've been
1750 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07001751 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001752 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
1753 encoder.GetStartBitrateKbps());
1754
1755 DestroyStreams();
1756}
1757
perkj57c21f92016-06-17 07:27:16 -07001758// This test that if the encoder use an internal source, VideoEncoder::SetRates
1759// will be called with zero bitrate during initialization and that
1760// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
1761// with zero bitrate.
1762TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
1763 class StartStopBitrateObserver : public test::FakeEncoder {
1764 public:
1765 StartStopBitrateObserver()
1766 : FakeEncoder(Clock::GetRealTimeClock()),
1767 encoder_init_(false, false),
Erik Språng08127a92016-11-16 16:41:30 +01001768 bitrate_changed_(false, false) {}
perkj57c21f92016-06-17 07:27:16 -07001769 int32_t InitEncode(const VideoCodec* config,
1770 int32_t number_of_cores,
1771 size_t max_payload_size) override {
1772 rtc::CritScope lock(&crit_);
perkj57c21f92016-06-17 07:27:16 -07001773 encoder_init_.Set();
1774 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1775 }
1776
Erik Språng08127a92016-11-16 16:41:30 +01001777 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
1778 uint32_t framerate) override {
perkj57c21f92016-06-17 07:27:16 -07001779 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01001780 bitrate_kbps_ = rtc::Optional<int>(bitrate.get_sum_kbps());
perkj57c21f92016-06-17 07:27:16 -07001781 bitrate_changed_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01001782 return FakeEncoder::SetRateAllocation(bitrate, framerate);
perkj57c21f92016-06-17 07:27:16 -07001783 }
1784
1785 bool WaitForEncoderInit() {
1786 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1787 }
Erik Språng08127a92016-11-16 16:41:30 +01001788
1789 bool WaitBitrateChanged(bool non_zero) {
1790 do {
1791 rtc::Optional<int> bitrate_kbps;
1792 {
1793 rtc::CritScope lock(&crit_);
1794 bitrate_kbps = bitrate_kbps_;
1795 }
1796 if (!bitrate_kbps)
1797 continue;
1798
1799 if ((non_zero && *bitrate_kbps > 0) ||
1800 (!non_zero && *bitrate_kbps == 0)) {
1801 return true;
1802 }
1803 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
1804 return false;
perkj57c21f92016-06-17 07:27:16 -07001805 }
1806
1807 private:
1808 rtc::CriticalSection crit_;
1809 rtc::Event encoder_init_;
1810 rtc::Event bitrate_changed_;
Erik Språng08127a92016-11-16 16:41:30 +01001811 rtc::Optional<int> bitrate_kbps_ GUARDED_BY(crit_);
perkj57c21f92016-06-17 07:27:16 -07001812 };
1813
skvlad11a9cbf2016-10-07 11:53:05 -07001814 CreateSenderCall(Call::Config(&event_log_));
perkj57c21f92016-06-17 07:27:16 -07001815
1816 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001817 CreateSendConfig(1, 0, 0, &transport);
perkj57c21f92016-06-17 07:27:16 -07001818
Sergey Ulanove2b15012016-11-22 16:08:30 -08001819 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
1820
perkj57c21f92016-06-17 07:27:16 -07001821 StartStopBitrateObserver encoder;
1822 video_send_config_.encoder_settings.encoder = &encoder;
1823 video_send_config_.encoder_settings.internal_source = true;
1824
1825 CreateVideoStreams();
1826
1827 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01001828
perkj57c21f92016-06-17 07:27:16 -07001829 video_send_stream_->Start();
Erik Språng08127a92016-11-16 16:41:30 +01001830 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
1831
perkj57c21f92016-06-17 07:27:16 -07001832 video_send_stream_->Stop();
Erik Språng08127a92016-11-16 16:41:30 +01001833 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
1834
perkj57c21f92016-06-17 07:27:16 -07001835 video_send_stream_->Start();
Erik Språng08127a92016-11-16 16:41:30 +01001836 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07001837
1838 DestroyStreams();
1839}
1840
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001841TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07001842 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001843 public:
Peter Boström5811a392015-12-10 13:02:50 +01001844 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001845
nissed30a1112016-04-18 05:15:22 -07001846 void OnFrame(const VideoFrame& video_frame) override {
1847 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01001848 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001849 }
1850
1851 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01001852 const int kWaitFrameTimeoutMs = 3000;
1853 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001854 << "Timeout while waiting for output frames.";
1855 }
1856
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001857 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001858 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001859 }
1860
1861 private:
1862 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001863 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001864
1865 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01001866 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001867 };
1868
1869 // Initialize send stream.
skvlad11a9cbf2016-10-07 11:53:05 -07001870 CreateSenderCall(Call::Config(&event_log_));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001871
solenberg4fbae2b2015-08-28 04:07:10 -07001872 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001873 CreateSendConfig(1, 0, 0, &transport);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001874 FrameObserver observer;
stefanff483612015-12-21 03:14:00 -08001875 video_send_config_.pre_encode_callback = &observer;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001876 CreateVideoStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001877
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001878 // Prepare five input frames. Send ordinary VideoFrame and texture frames
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001879 // alternatively.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001880 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07001881 int width = 168;
1882 int height = 132;
1883
Peter Boströmeb66e802015-06-05 11:08:03 +02001884 test::FakeNativeHandle* handle1 = new test::FakeNativeHandle();
1885 test::FakeNativeHandle* handle2 = new test::FakeNativeHandle();
1886 test::FakeNativeHandle* handle3 = new test::FakeNativeHandle();
Peter Boström13f61df2016-01-04 22:36:38 +01001887 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001888 handle1, width, height, 1, 1, kVideoRotation_0));
Peter Boström13f61df2016-01-04 22:36:38 +01001889 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001890 handle2, width, height, 2, 2, kVideoRotation_0));
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001891 input_frames.push_back(CreateVideoFrame(width, height, 3));
1892 input_frames.push_back(CreateVideoFrame(width, height, 4));
Peter Boström13f61df2016-01-04 22:36:38 +01001893 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001894 handle3, width, height, 5, 5, kVideoRotation_0));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001895
stefanff483612015-12-21 03:14:00 -08001896 video_send_stream_->Start();
perkja49cbd32016-09-16 07:53:41 -07001897 test::FrameForwarder forwarder;
perkj803d97f2016-11-01 11:45:46 -07001898 video_send_stream_->SetSource(
1899 &forwarder, VideoSendStream::DegradationPreference::kBalanced);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001900 for (size_t i = 0; i < input_frames.size(); i++) {
perkja49cbd32016-09-16 07:53:41 -07001901 forwarder.IncomingCapturedFrame(input_frames[i]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001902 // Wait until the output frame is received before sending the next input
1903 // frame. Or the previous input frame may be replaced without delivering.
1904 observer.WaitOutputFrame();
1905 }
stefanff483612015-12-21 03:14:00 -08001906 video_send_stream_->Stop();
perkj803d97f2016-11-01 11:45:46 -07001907 video_send_stream_->SetSource(
1908 nullptr, VideoSendStream::DegradationPreference::kBalanced);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001909
1910 // Test if the input and output frames are the same. render_time_ms and
1911 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001912 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001913
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001914 DestroyStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001915}
1916
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001917void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
1918 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001919 EXPECT_EQ(frames1.size(), frames2.size());
1920 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07001921 // Compare frame buffers, since we don't care about differing timestamps.
1922 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
1923 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001924}
1925
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001926VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001927 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08001928 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001929 memset(buffer.get(), data, kSizeY);
nissef0a7c5a2016-10-31 05:48:07 -07001930 VideoFrame frame(
1931 I420Buffer::Create(width, height, width, width / 2, width / 2),
1932 kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001933 frame.set_timestamp(data);
1934 frame.set_render_time_ms(data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001935 return frame;
1936}
1937
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001938TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
1939 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
1940 public:
1941 EncoderStateObserver()
1942 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001943 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001944 initialized_(false),
1945 callback_registered_(false),
1946 num_releases_(0),
1947 released_(false) {}
1948
1949 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02001950 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001951 return released_;
1952 }
1953
1954 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02001955 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001956 return initialized_ && callback_registered_;
1957 }
1958
1959 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02001960 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001961 return num_releases_;
1962 }
1963
1964 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001965 int32_t InitEncode(const VideoCodec* codecSettings,
1966 int32_t numberOfCores,
1967 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001968 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001969 EXPECT_FALSE(initialized_);
1970 initialized_ = true;
1971 released_ = false;
1972 return 0;
1973 }
1974
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001975 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001976 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07001977 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001978 EXPECT_TRUE(IsReadyForEncode());
1979
Peter Boström5811a392015-12-10 13:02:50 +01001980 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001981 return 0;
1982 }
1983
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001984 int32_t RegisterEncodeCompleteCallback(
1985 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001986 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001987 EXPECT_TRUE(initialized_);
1988 callback_registered_ = true;
1989 return 0;
1990 }
1991
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001992 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001993 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001994 EXPECT_TRUE(IsReadyForEncode());
1995 EXPECT_FALSE(released_);
1996 initialized_ = false;
1997 callback_registered_ = false;
1998 released_ = true;
1999 ++num_releases_;
2000 return 0;
2001 }
2002
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002003 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002004 EXPECT_TRUE(IsReadyForEncode());
2005 return 0;
2006 }
2007
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002008 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002009 EXPECT_TRUE(IsReadyForEncode());
2010 return 0;
2011 }
2012
stefanff483612015-12-21 03:14:00 -08002013 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002014 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002015 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002016 stream_ = send_stream;
2017 }
2018
stefanff483612015-12-21 03:14:00 -08002019 void ModifyVideoConfigs(
2020 VideoSendStream::Config* send_config,
2021 std::vector<VideoReceiveStream::Config>* receive_configs,
2022 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002023 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07002024 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002025 }
2026
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002027 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002028 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
Per21d45d22016-10-30 21:37:57 +01002029 EXPECT_EQ(0u, num_releases());
perkj26091b12016-09-01 01:17:40 -07002030 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
Per21d45d22016-10-30 21:37:57 +01002031 EXPECT_EQ(0u, num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002032 stream_->Stop();
2033 // Encoder should not be released before destroying the VideoSendStream.
2034 EXPECT_FALSE(IsReleased());
2035 EXPECT_TRUE(IsReadyForEncode());
2036 stream_->Start();
2037 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002038 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002039 }
2040
Peter Boströmf2f82832015-05-01 13:00:41 +02002041 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002042 VideoSendStream* stream_;
2043 bool initialized_ GUARDED_BY(crit_);
2044 bool callback_registered_ GUARDED_BY(crit_);
2045 size_t num_releases_ GUARDED_BY(crit_);
2046 bool released_ GUARDED_BY(crit_);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002047 VideoEncoderConfig encoder_config_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002048 } test_encoder;
2049
stefane74eef12016-01-08 06:47:13 -08002050 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002051
2052 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002053 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002054}
2055
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002056TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2057 class VideoCodecConfigObserver : public test::SendTest,
2058 public test::FakeEncoder {
2059 public:
2060 VideoCodecConfigObserver()
2061 : SendTest(kDefaultTimeoutMs),
2062 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002063 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002064 num_initializations_(0),
2065 stream_(nullptr) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002066
2067 private:
stefanff483612015-12-21 03:14:00 -08002068 void ModifyVideoConfigs(
2069 VideoSendStream::Config* send_config,
2070 std::vector<VideoReceiveStream::Config>* receive_configs,
2071 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002072 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07002073 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002074 }
2075
stefanff483612015-12-21 03:14:00 -08002076 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002077 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002078 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002079 stream_ = send_stream;
2080 }
2081
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002082 int32_t InitEncode(const VideoCodec* config,
2083 int32_t number_of_cores,
2084 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002085 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002086 // Verify default values.
2087 EXPECT_EQ(kRealtimeVideo, config->mode);
2088 } else {
2089 // Verify that changed values are propagated.
2090 EXPECT_EQ(kScreensharing, config->mode);
2091 }
2092 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002093 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002094 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2095 }
2096
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002097 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002098 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002099 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002100
Erik Språng143cec12015-04-28 10:01:41 +02002101 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
perkj26091b12016-09-01 01:17:40 -07002102 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002103 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002104 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002105 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2106 "new encoder settings.";
2107 }
2108
pbos14fe7082016-04-20 06:35:56 -07002109 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002110 size_t num_initializations_;
2111 VideoSendStream* stream_;
2112 VideoEncoderConfig encoder_config_;
2113 } test;
2114
stefane74eef12016-01-08 06:47:13 -08002115 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002116}
2117
Peter Boström53eda3d2015-03-27 15:53:18 +01002118static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
2119template <typename T>
2120class VideoCodecConfigObserver : public test::SendTest,
2121 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002122 public:
2123 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2124 const char* codec_name)
2125 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2126 FakeEncoder(Clock::GetRealTimeClock()),
2127 video_codec_type_(video_codec_type),
2128 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002129 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002130 num_initializations_(0),
2131 stream_(nullptr) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002132 memset(&encoder_settings_, 0, sizeof(encoder_settings_));
2133 }
2134
2135 private:
perkjfa10b552016-10-02 23:45:26 -07002136 class VideoStreamFactory
2137 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2138 public:
2139 VideoStreamFactory() {}
2140
2141 private:
2142 std::vector<VideoStream> CreateEncoderStreams(
2143 int width,
2144 int height,
2145 const VideoEncoderConfig& encoder_config) override {
2146 std::vector<VideoStream> streams =
2147 test::CreateVideoStreams(width, height, encoder_config);
2148 for (size_t i = 0; i < streams.size(); ++i) {
2149 streams[i].temporal_layer_thresholds_bps.resize(
2150 kVideoCodecConfigObserverNumberOfTemporalLayers - 1);
2151 }
2152 return streams;
2153 }
2154 };
2155
stefanff483612015-12-21 03:14:00 -08002156 void ModifyVideoConfigs(
2157 VideoSendStream::Config* send_config,
2158 std::vector<VideoReceiveStream::Config>* receive_configs,
2159 VideoEncoderConfig* encoder_config) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002160 send_config->encoder_settings.encoder = this;
2161 send_config->encoder_settings.payload_name = codec_name_;
2162
kthelgason29a44e32016-09-27 03:52:02 -07002163 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002164 encoder_config->video_stream_factory =
2165 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002166 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002167 }
2168
stefanff483612015-12-21 03:14:00 -08002169 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002170 VideoSendStream* send_stream,
2171 const std::vector<VideoReceiveStream*>& receive_streams) override {
2172 stream_ = send_stream;
2173 }
2174
2175 int32_t InitEncode(const VideoCodec* config,
2176 int32_t number_of_cores,
2177 size_t max_payload_size) override {
2178 EXPECT_EQ(video_codec_type_, config->codecType);
2179 VerifyCodecSpecifics(*config);
2180 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002181 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002182 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2183 }
2184
2185 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002186 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2187 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002188
2189 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002190 EXPECT_TRUE(
2191 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002192 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002193
2194 encoder_settings_.frameDroppingOn = true;
kthelgason29a44e32016-09-27 03:52:02 -07002195 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002196 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002197 ASSERT_TRUE(
2198 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002199 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002200 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2201 "new encoder settings.";
2202 }
2203
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002204 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002205 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002206 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002207 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2208 return 0;
2209 }
2210
2211 T encoder_settings_;
2212 const VideoCodecType video_codec_type_;
2213 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002214 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002215 size_t num_initializations_;
2216 VideoSendStream* stream_;
2217 VideoEncoderConfig encoder_config_;
2218};
2219
2220template <>
2221void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2222 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002223 EXPECT_EQ(
2224 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002225}
kthelgason29a44e32016-09-27 03:52:02 -07002226
2227template <>
2228rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2229VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2230 return new rtc::RefCountedObject<
2231 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2232}
2233
Peter Boström53eda3d2015-03-27 15:53:18 +01002234template <>
2235void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2236 const VideoCodec& config) const {
2237 // Check that the number of temporal layers has propagated properly to
2238 // VideoCodec.
2239 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002240 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002241
2242 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2243 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2244 config.simulcastStream[i].numberOfTemporalLayers);
2245 }
2246
2247 // Set expected temporal layers as they should have been set when
Erik Språng08127a92016-11-16 16:41:30 +01002248 // reconfiguring the encoder and not match the set config. Also copy the
2249 // TemporalLayersFactory pointer that has been injected by ViEEncoder.
Peter Boström53eda3d2015-03-27 15:53:18 +01002250 VideoCodecVP8 encoder_settings = encoder_settings_;
2251 encoder_settings.numberOfTemporalLayers =
2252 kVideoCodecConfigObserverNumberOfTemporalLayers;
Erik Språng08127a92016-11-16 16:41:30 +01002253 encoder_settings.tl_factory = config.VP8().tl_factory;
hta257dc392016-10-25 09:05:06 -07002254 EXPECT_EQ(
2255 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002256}
kthelgason29a44e32016-09-27 03:52:02 -07002257
2258template <>
2259rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2260VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2261 return new rtc::RefCountedObject<
2262 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2263}
2264
Peter Boström53eda3d2015-03-27 15:53:18 +01002265template <>
2266void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2267 const VideoCodec& config) const {
2268 // Check that the number of temporal layers has propagated properly to
2269 // VideoCodec.
2270 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002271 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002272
2273 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2274 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2275 config.simulcastStream[i].numberOfTemporalLayers);
2276 }
2277
2278 // Set expected temporal layers as they should have been set when
2279 // reconfiguring the encoder and not match the set config.
2280 VideoCodecVP9 encoder_settings = encoder_settings_;
2281 encoder_settings.numberOfTemporalLayers =
2282 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002283 EXPECT_EQ(
2284 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002285}
2286
kthelgason29a44e32016-09-27 03:52:02 -07002287template <>
2288rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2289VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2290 return new rtc::RefCountedObject<
2291 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2292}
2293
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002294TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002295 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002296 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002297}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002298
Peter Boström53eda3d2015-03-27 15:53:18 +01002299TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2300 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002301 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002302}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002303
Peter Boström53eda3d2015-03-27 15:53:18 +01002304TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2305 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002306 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002307}
2308
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002309TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002310 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002311 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002312 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2313 rtp_packets_sent_(0),
2314 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002315
2316 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002317 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002318 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002319 RTPHeader header;
2320 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002321 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002322 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2323 return SEND_PACKET;
2324 }
2325
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002326 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002327 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002328 test::RtcpPacketParser parser;
2329 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002330
danilchap3dc929e2016-11-02 08:21:59 -07002331 if (parser.sender_report()->num_packets() > 0) {
2332 // Only compare sent media bytes if SenderPacketCount matches the
2333 // number of sent rtp packets (a new rtp packet could be sent before
2334 // the rtcp packet).
2335 if (parser.sender_report()->sender_octet_count() > 0 &&
2336 parser.sender_report()->sender_packet_count() ==
2337 rtp_packets_sent_) {
2338 EXPECT_EQ(media_bytes_sent_,
2339 parser.sender_report()->sender_octet_count());
2340 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002341 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002342 }
2343
2344 return SEND_PACKET;
2345 }
2346
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002347 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002348 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002349 }
2350
stefan4b569042015-11-11 06:39:57 -08002351 rtc::CriticalSection crit_;
2352 size_t rtp_packets_sent_ GUARDED_BY(&crit_);
2353 size_t media_bytes_sent_ GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002354 } test;
2355
stefane74eef12016-01-08 06:47:13 -08002356 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002357}
2358
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002359TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
2360 static const int kScreencastTargetBitrateKbps = 200;
perkjfa10b552016-10-02 23:45:26 -07002361
2362 class VideoStreamFactory
2363 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2364 public:
2365 VideoStreamFactory() {}
2366
2367 private:
2368 std::vector<VideoStream> CreateEncoderStreams(
2369 int width,
2370 int height,
2371 const VideoEncoderConfig& encoder_config) override {
2372 std::vector<VideoStream> streams =
2373 test::CreateVideoStreams(width, height, encoder_config);
2374 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
2375 streams[0].temporal_layer_thresholds_bps.push_back(
2376 kScreencastTargetBitrateKbps * 1000);
2377 return streams;
2378 }
2379 };
2380
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002381 class ScreencastTargetBitrateTest : public test::SendTest,
2382 public test::FakeEncoder {
2383 public:
2384 ScreencastTargetBitrateTest()
2385 : SendTest(kDefaultTimeoutMs),
2386 test::FakeEncoder(Clock::GetRealTimeClock()) {}
2387
2388 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002389 int32_t InitEncode(const VideoCodec* config,
2390 int32_t number_of_cores,
2391 size_t max_payload_size) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002392 EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps),
2393 config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002394 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002395 return test::FakeEncoder::InitEncode(
2396 config, number_of_cores, max_payload_size);
2397 }
stefanff483612015-12-21 03:14:00 -08002398 void ModifyVideoConfigs(
2399 VideoSendStream::Config* send_config,
2400 std::vector<VideoReceiveStream::Config>* receive_configs,
2401 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002402 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002403 EXPECT_EQ(1u, encoder_config->number_of_streams);
2404 encoder_config->video_stream_factory =
2405 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002406 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002407 }
2408
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002409 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002410 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002411 << "Timed out while waiting for the encoder to be initialized.";
2412 }
2413 } test;
2414
stefane74eef12016-01-08 06:47:13 -08002415 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002416}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002417
philipelc6957c72016-04-28 15:52:49 +02002418TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002419 // These are chosen to be "kind of odd" to not be accidentally checked against
2420 // default values.
2421 static const int kMinBitrateKbps = 137;
2422 static const int kStartBitrateKbps = 345;
2423 static const int kLowerMaxBitrateKbps = 312;
2424 static const int kMaxBitrateKbps = 413;
2425 static const int kIncreasedStartBitrateKbps = 451;
2426 static const int kIncreasedMaxBitrateKbps = 597;
2427 class EncoderBitrateThresholdObserver : public test::SendTest,
2428 public test::FakeEncoder {
2429 public:
2430 EncoderBitrateThresholdObserver()
2431 : SendTest(kDefaultTimeoutMs),
2432 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002433 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002434 bitrate_changed_event_(false, false),
2435 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002436 num_initializations_(0),
2437 call_(nullptr),
2438 send_stream_(nullptr) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002439
2440 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002441 int32_t InitEncode(const VideoCodec* codecSettings,
2442 int32_t numberOfCores,
2443 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002444 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2445 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002446 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002447 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2448 codecSettings->minBitrate);
2449 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2450 codecSettings->startBitrate);
2451 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2452 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002453 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002454 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002455 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2456 codecSettings->maxBitrate);
2457 // The start bitrate should be kept (-1) and capped to the max bitrate.
2458 // Since this is not an end-to-end call no receiver should have been
2459 // returning a REMB that could lower this estimate.
2460 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002461 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002462 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2463 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002464 // The start bitrate will be whatever the rate BitRateController
2465 // has currently configured but in the span of the set max and min
2466 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002467 }
2468 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002469 init_encode_event_.Set();
2470
pbos@webrtc.org00873182014-11-25 14:03:34 +00002471 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2472 maxPayloadSize);
2473 }
2474
Erik Språng08127a92016-11-16 16:41:30 +01002475 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
2476 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002477 {
2478 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002479 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2480 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002481 }
Erik Språng08127a92016-11-16 16:41:30 +01002482 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002483 }
2484 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002485 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002486 }
2487
2488 void WaitForSetRates(uint32_t expected_bitrate) {
2489 EXPECT_TRUE(
2490 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2491 << "Timed out while waiting encoder rate to be set.";
2492 rtc::CritScope lock(&crit_);
2493 EXPECT_EQ(expected_bitrate, target_bitrate_);
2494 }
2495
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002496 Call::Config GetSenderCallConfig() override {
skvlad11a9cbf2016-10-07 11:53:05 -07002497 Call::Config config(&event_log_);
Stefan Holmere5904162015-03-26 11:11:06 +01002498 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2499 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2500 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002501 return config;
2502 }
2503
perkjfa10b552016-10-02 23:45:26 -07002504 class VideoStreamFactory
2505 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2506 public:
2507 explicit VideoStreamFactory(int min_bitrate_bps)
2508 : min_bitrate_bps_(min_bitrate_bps) {}
2509
2510 private:
2511 std::vector<VideoStream> CreateEncoderStreams(
2512 int width,
2513 int height,
2514 const VideoEncoderConfig& encoder_config) override {
2515 std::vector<VideoStream> streams =
2516 test::CreateVideoStreams(width, height, encoder_config);
2517 streams[0].min_bitrate_bps = min_bitrate_bps_;
2518 return streams;
2519 }
2520
2521 const int min_bitrate_bps_;
2522 };
2523
stefanff483612015-12-21 03:14:00 -08002524 void ModifyVideoConfigs(
2525 VideoSendStream::Config* send_config,
2526 std::vector<VideoReceiveStream::Config>* receive_configs,
2527 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002528 send_config->encoder_settings.encoder = this;
2529 // Set bitrates lower/higher than min/max to make sure they are properly
2530 // capped.
perkjfa10b552016-10-02 23:45:26 -07002531 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2532 // Create a new StreamFactory to be able to set
2533 // |VideoStream.min_bitrate_bps|.
2534 encoder_config->video_stream_factory =
2535 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002536 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002537 }
2538
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002539 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002540 call_ = sender_call;
2541 }
2542
stefanff483612015-12-21 03:14:00 -08002543 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002544 VideoSendStream* send_stream,
2545 const std::vector<VideoReceiveStream*>& receive_streams) override {
2546 send_stream_ = send_stream;
2547 }
2548
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002549 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002550 ASSERT_TRUE(
2551 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002552 << "Timed out while waiting for encoder to be configured.";
2553 WaitForSetRates(kStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002554 Call::Config::BitrateConfig bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002555 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2556 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2557 call_->SetBitrateConfig(bitrate_config);
perkj26091b12016-09-01 01:17:40 -07002558 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2559 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002560 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002561 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002562 ASSERT_TRUE(
2563 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002564 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002565 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002566 WaitForSetRates(kLowerMaxBitrateKbps);
2567
2568 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2569 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2570 ASSERT_TRUE(
2571 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002572 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002573 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002574 // Expected target bitrate is the start bitrate set in the call to
2575 // call_->SetBitrateConfig.
2576 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002577 }
2578
pbos14fe7082016-04-20 06:35:56 -07002579 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002580 rtc::Event bitrate_changed_event_;
2581 rtc::CriticalSection crit_;
2582 uint32_t target_bitrate_ GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002583
pbos@webrtc.org00873182014-11-25 14:03:34 +00002584 int num_initializations_;
2585 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002586 webrtc::VideoSendStream* send_stream_;
2587 webrtc::VideoEncoderConfig encoder_config_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002588 } test;
2589
stefane74eef12016-01-08 06:47:13 -08002590 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002591}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002592
2593TEST_F(VideoSendStreamTest, ReportsSentResolution) {
2594 static const size_t kNumStreams = 3;
2595 // Unusual resolutions to make sure that they are the ones being reported.
2596 static const struct {
2597 int width;
2598 int height;
2599 } kEncodedResolution[kNumStreams] = {
2600 {241, 181}, {300, 121}, {121, 221}};
2601 class ScreencastTargetBitrateTest : public test::SendTest,
2602 public test::FakeEncoder {
2603 public:
2604 ScreencastTargetBitrateTest()
2605 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002606 test::FakeEncoder(Clock::GetRealTimeClock()),
2607 send_stream_(nullptr) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002608
2609 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002610 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002611 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002612 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002613 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002614 specifics.codecType = kVideoCodecGeneric;
2615
2616 uint8_t buffer[16] = {0};
2617 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
2618 encoded._timeStamp = input_image.timestamp();
2619 encoded.capture_time_ms_ = input_image.render_time_ms();
2620
2621 for (size_t i = 0; i < kNumStreams; ++i) {
2622 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
2623 encoded._frameType = (*frame_types)[i];
2624 encoded._encodedWidth = kEncodedResolution[i].width;
2625 encoded._encodedHeight = kEncodedResolution[i].height;
Peter Boström74f6e9e2016-04-04 17:56:10 +02002626 RTC_DCHECK(callback_);
sergeyu2cb155a2016-11-04 11:39:29 -07002627 if (callback_->OnEncodedImage(encoded, &specifics, nullptr).error !=
2628 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002629 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07002630 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002631 }
2632
Peter Boström5811a392015-12-10 13:02:50 +01002633 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002634 return 0;
2635 }
stefanff483612015-12-21 03:14:00 -08002636 void ModifyVideoConfigs(
2637 VideoSendStream::Config* send_config,
2638 std::vector<VideoReceiveStream::Config>* receive_configs,
2639 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002640 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002641 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002642 }
2643
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002644 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002645
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002646 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002647 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002648 << "Timed out while waiting for the encoder to send one frame.";
2649 VideoSendStream::Stats stats = send_stream_->GetStats();
2650
2651 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002652 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002653 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002654 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002655 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002656 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002657 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002658 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
2659 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002660 }
2661 }
2662
stefanff483612015-12-21 03:14:00 -08002663 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002664 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002665 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002666 send_stream_ = send_stream;
2667 }
2668
2669 VideoSendStream* send_stream_;
2670 } test;
2671
stefane74eef12016-01-08 06:47:13 -08002672 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002673}
philipel0f9af012015-09-01 07:01:51 -07002674
Peter Boström12996152016-05-14 02:03:18 +02002675#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01002676class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07002677 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01002678 Vp9HeaderObserver()
2679 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
philipel7fabd462015-09-03 04:42:32 -07002680 vp9_encoder_(VP9Encoder::Create()),
Åsa Perssonff24c042015-12-04 10:58:08 +01002681 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
2682 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07002683 frames_sent_(0),
2684 expected_width_(0),
2685 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07002686
stefanff483612015-12-21 03:14:00 -08002687 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07002688 VideoSendStream::Config* send_config,
2689 std::vector<VideoReceiveStream::Config>* receive_configs,
2690 VideoEncoderConfig* encoder_config) {}
2691
Åsa Perssonff24c042015-12-04 10:58:08 +01002692 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07002693
2694 private:
2695 const int kVp9PayloadType = 105;
2696
perkjfa10b552016-10-02 23:45:26 -07002697 class VideoStreamFactory
2698 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2699 public:
2700 explicit VideoStreamFactory(size_t number_of_temporal_layers)
2701 : number_of_temporal_layers_(number_of_temporal_layers) {}
2702
2703 private:
2704 std::vector<VideoStream> CreateEncoderStreams(
2705 int width,
2706 int height,
2707 const VideoEncoderConfig& encoder_config) override {
2708 std::vector<VideoStream> streams =
2709 test::CreateVideoStreams(width, height, encoder_config);
2710 streams[0].temporal_layer_thresholds_bps.resize(
2711 number_of_temporal_layers_ - 1);
2712 return streams;
2713 }
2714
2715 const size_t number_of_temporal_layers_;
2716 };
2717
stefanff483612015-12-21 03:14:00 -08002718 void ModifyVideoConfigs(
2719 VideoSendStream::Config* send_config,
2720 std::vector<VideoReceiveStream::Config>* receive_configs,
2721 VideoEncoderConfig* encoder_config) override {
philipel7fabd462015-09-03 04:42:32 -07002722 send_config->encoder_settings.encoder = vp9_encoder_.get();
philipel0f9af012015-09-01 07:01:51 -07002723 send_config->encoder_settings.payload_name = "VP9";
2724 send_config->encoder_settings.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08002725 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07002726 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
2727 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07002728 EXPECT_EQ(1u, encoder_config->number_of_streams);
2729 encoder_config->video_stream_factory =
2730 new rtc::RefCountedObject<VideoStreamFactory>(
2731 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07002732 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07002733 }
2734
perkjfa10b552016-10-02 23:45:26 -07002735 void ModifyVideoCaptureStartResolution(int* width,
2736 int* height,
2737 int* frame_rate) override {
2738 expected_width_ = *width;
2739 expected_height_ = *height;
2740 }
2741
philipel0f9af012015-09-01 07:01:51 -07002742 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002743 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
2744 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002745 }
2746
2747 Action OnSendRtp(const uint8_t* packet, size_t length) override {
2748 RTPHeader header;
2749 EXPECT_TRUE(parser_->Parse(packet, length, &header));
2750
Åsa Perssonff24c042015-12-04 10:58:08 +01002751 EXPECT_EQ(kVp9PayloadType, header.payloadType);
2752 const uint8_t* payload = packet + header.headerLength;
2753 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07002754
Åsa Perssonff24c042015-12-04 10:58:08 +01002755 bool new_packet = packets_sent_ == 0 ||
2756 IsNewerSequenceNumber(header.sequenceNumber,
2757 last_header_.sequenceNumber);
2758 if (payload_length > 0 && new_packet) {
2759 RtpDepacketizer::ParsedPayload parsed;
2760 RtpDepacketizerVp9 depacketizer;
2761 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
2762 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
2763 // Verify common fields for all configurations.
2764 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
2765 CompareConsecutiveFrames(header, parsed.type.Video);
2766 // Verify configuration specific settings.
2767 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07002768
Åsa Perssonff24c042015-12-04 10:58:08 +01002769 ++packets_sent_;
2770 if (header.markerBit) {
2771 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002772 }
Åsa Perssonff24c042015-12-04 10:58:08 +01002773 last_header_ = header;
2774 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07002775 }
philipel0f9af012015-09-01 07:01:51 -07002776 return SEND_PACKET;
2777 }
2778
philipel7fabd462015-09-03 04:42:32 -07002779 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01002780 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
2781 if (last_vp9_.picture_id > vp9.picture_id) {
2782 return vp9.picture_id == 0; // Wrap.
2783 } else {
2784 return vp9.picture_id == last_vp9_.picture_id + 1;
2785 }
2786 }
2787
2788 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01002789 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
2790 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
2791 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
2792 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
2793 vp9.spatial_idx);
2794 }
2795
2796 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
2797 uint8_t num_layers) const {
2798 switch (num_layers) {
2799 case 0:
2800 VerifyTemporalLayerStructure0(vp9);
2801 break;
2802 case 1:
2803 VerifyTemporalLayerStructure1(vp9);
2804 break;
2805 case 2:
2806 VerifyTemporalLayerStructure2(vp9);
2807 break;
2808 case 3:
2809 VerifyTemporalLayerStructure3(vp9);
2810 break;
2811 default:
2812 RTC_NOTREACHED();
2813 }
2814 }
2815
2816 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
2817 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
2818 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
2819 EXPECT_FALSE(vp9.temporal_up_switch);
2820 }
2821
2822 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
2823 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2824 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
2825 EXPECT_FALSE(vp9.temporal_up_switch);
2826 }
2827
2828 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
2829 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2830 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
2831 EXPECT_LE(vp9.temporal_idx, 1);
2832 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
2833 if (IsNewPictureId(vp9)) {
2834 uint8_t expected_tid =
2835 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
2836 EXPECT_EQ(expected_tid, vp9.temporal_idx);
2837 }
2838 }
2839
2840 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
2841 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2842 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
2843 EXPECT_LE(vp9.temporal_idx, 2);
2844 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
2845 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
2846 switch (vp9.temporal_idx) {
2847 case 0:
2848 EXPECT_EQ(2, last_vp9_.temporal_idx);
2849 EXPECT_FALSE(vp9.temporal_up_switch);
2850 break;
2851 case 1:
2852 EXPECT_EQ(2, last_vp9_.temporal_idx);
2853 EXPECT_TRUE(vp9.temporal_up_switch);
2854 break;
2855 case 2:
2856 EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
2857 break;
2858 }
2859 }
2860 }
2861
2862 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
2863 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
2864 return;
2865
2866 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
2867 if (vp9.temporal_idx == 0)
2868 ++expected_tl0_idx;
2869 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
2870 }
2871
2872 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
2873 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
2874 }
2875
2876 // Flexible mode (F=1): Non-flexible mode (F=0):
2877 //
2878 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2879 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
2880 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2881 // I: |M| PICTURE ID | I: |M| PICTURE ID |
2882 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2883 // M: | EXTENDED PID | M: | EXTENDED PID |
2884 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2885 // L: | T |U| S |D| L: | T |U| S |D|
2886 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2887 // P,F: | P_DIFF |X|N| | TL0PICIDX |
2888 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2889 // X: |EXTENDED P_DIFF| V: | SS .. |
2890 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2891 // V: | SS .. |
2892 // +-+-+-+-+-+-+-+-+
2893 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
2894 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
2895 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
2896 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
2897 EXPECT_GE(vp9.spatial_idx, 0); // S
2898 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
2899 if (vp9.ss_data_available) // V
2900 VerifySsData(vp9);
2901
2902 if (frames_sent_ == 0)
2903 EXPECT_FALSE(vp9.inter_pic_predicted); // P
2904
2905 if (!vp9.inter_pic_predicted) {
2906 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
2907 EXPECT_FALSE(vp9.temporal_up_switch);
2908 }
2909 }
2910
2911 // Scalability structure (SS).
2912 //
2913 // +-+-+-+-+-+-+-+-+
2914 // V: | N_S |Y|G|-|-|-|
2915 // +-+-+-+-+-+-+-+-+
2916 // Y: | WIDTH | N_S + 1 times
2917 // +-+-+-+-+-+-+-+-+
2918 // | HEIGHT |
2919 // +-+-+-+-+-+-+-+-+
2920 // G: | N_G |
2921 // +-+-+-+-+-+-+-+-+
2922 // N_G: | T |U| R |-|-| N_G times
2923 // +-+-+-+-+-+-+-+-+
2924 // | P_DIFF | R times
2925 // +-+-+-+-+-+-+-+-+
2926 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
2927 EXPECT_TRUE(vp9.ss_data_available); // V
2928 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
2929 vp9.num_spatial_layers);
2930 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07002931 int expected_width = expected_width_;
2932 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02002933 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01002934 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
2935 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
2936 expected_width /= 2;
2937 expected_height /= 2;
2938 }
2939 }
2940
2941 void CompareConsecutiveFrames(const RTPHeader& header,
2942 const RTPVideoHeader& video) const {
2943 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
2944
2945 bool new_frame = packets_sent_ == 0 ||
2946 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
2947 EXPECT_EQ(new_frame, video.isFirstPacket);
2948 if (!new_frame) {
2949 EXPECT_FALSE(last_header_.markerBit);
2950 EXPECT_EQ(last_header_.timestamp, header.timestamp);
2951 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
2952 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
2953 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
2954 VerifySpatialIdxWithinFrame(vp9);
2955 return;
2956 }
2957 // New frame.
2958 EXPECT_TRUE(vp9.beginning_of_frame);
2959
2960 // Compare with last packet in previous frame.
2961 if (frames_sent_ == 0)
2962 return;
2963 EXPECT_TRUE(last_vp9_.end_of_frame);
2964 EXPECT_TRUE(last_header_.markerBit);
2965 EXPECT_TRUE(ContinuousPictureId(vp9));
2966 VerifyTl0Idx(vp9);
2967 }
2968
kwiberg27f982b2016-03-01 11:52:33 -08002969 std::unique_ptr<VP9Encoder> vp9_encoder_;
philipel0f9af012015-09-01 07:01:51 -07002970 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01002971 webrtc::VideoEncoderConfig encoder_config_;
2972 RTPHeader last_header_;
2973 RTPVideoHeaderVP9 last_vp9_;
2974 size_t packets_sent_;
2975 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07002976 int expected_width_;
2977 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07002978};
2979
Åsa Perssonff24c042015-12-04 10:58:08 +01002980TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
2981 const uint8_t kNumTemporalLayers = 1;
2982 const uint8_t kNumSpatialLayers = 1;
2983 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2984}
2985
2986TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
2987 const uint8_t kNumTemporalLayers = 2;
2988 const uint8_t kNumSpatialLayers = 1;
2989 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2990}
2991
2992TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
2993 const uint8_t kNumTemporalLayers = 3;
2994 const uint8_t kNumSpatialLayers = 1;
2995 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2996}
2997
2998TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
2999 const uint8_t kNumTemporalLayers = 1;
3000 const uint8_t kNumSpatialLayers = 2;
3001 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3002}
3003
3004TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3005 const uint8_t kNumTemporalLayers = 2;
3006 const uint8_t kNumSpatialLayers = 2;
3007 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3008}
3009
3010TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3011 const uint8_t kNumTemporalLayers = 3;
3012 const uint8_t kNumSpatialLayers = 2;
3013 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3014}
3015
3016void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3017 uint8_t num_spatial_layers) {
3018 static const size_t kNumFramesToSend = 100;
3019 // Set to < kNumFramesToSend and coprime to length of temporal layer
3020 // structures to verify temporal id reset on key frame.
3021 static const int kKeyFrameInterval = 31;
3022 class NonFlexibleMode : public Vp9HeaderObserver {
3023 public:
3024 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3025 : num_temporal_layers_(num_temporal_layers),
3026 num_spatial_layers_(num_spatial_layers),
3027 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
stefanff483612015-12-21 03:14:00 -08003028 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003029 VideoSendStream::Config* send_config,
3030 std::vector<VideoReceiveStream::Config>* receive_configs,
3031 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003032 vp9_settings_.flexibleMode = false;
3033 vp9_settings_.frameDroppingOn = false;
3034 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3035 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3036 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003037 }
3038
Åsa Perssonff24c042015-12-04 10:58:08 +01003039 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
3040 bool ss_data_expected = !vp9.inter_pic_predicted &&
3041 vp9.beginning_of_frame && vp9.spatial_idx == 0;
3042 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
3043 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted); // D
asapersson38bb8ad2015-12-14 01:41:19 -08003044 EXPECT_EQ(!vp9.inter_pic_predicted,
3045 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003046
3047 if (IsNewPictureId(vp9)) {
3048 EXPECT_EQ(0, vp9.spatial_idx);
3049 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
3050 }
3051
3052 VerifyFixedTemporalLayerStructure(vp9,
3053 l_field_ ? num_temporal_layers_ : 0);
3054
3055 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003056 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003057 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003058 const uint8_t num_temporal_layers_;
3059 const uint8_t num_spatial_layers_;
3060 const bool l_field_;
3061 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003062
stefane74eef12016-01-08 06:47:13 -08003063 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003064}
3065
asaperssond9f641e2016-01-21 01:11:35 -08003066TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3067 static const size_t kNumFramesToSend = 50;
3068 static const int kWidth = 4;
3069 static const int kHeight = 4;
3070 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3071 void ModifyVideoConfigsHook(
3072 VideoSendStream::Config* send_config,
3073 std::vector<VideoReceiveStream::Config>* receive_configs,
3074 VideoEncoderConfig* encoder_config) override {
3075 vp9_settings_.flexibleMode = false;
3076 vp9_settings_.numberOfTemporalLayers = 1;
3077 vp9_settings_.numberOfSpatialLayers = 1;
3078
perkjfa10b552016-10-02 23:45:26 -07003079 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003080 }
3081
3082 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3083 if (frames_sent_ > kNumFramesToSend)
3084 observation_complete_.Set();
3085 }
perkjfa10b552016-10-02 23:45:26 -07003086
3087 void ModifyVideoCaptureStartResolution(int* width,
3088 int* height,
3089 int* frame_rate) override {
3090 expected_width_ = kWidth;
3091 expected_height_ = kHeight;
3092 *width = kWidth;
3093 *height = kHeight;
3094 }
asaperssond9f641e2016-01-21 01:11:35 -08003095 } test;
3096
3097 RunBaseTest(&test);
3098}
3099
Åsa Perssonff24c042015-12-04 10:58:08 +01003100TEST_F(VideoSendStreamTest, Vp9FlexModeRefCount) {
3101 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003102 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003103 VideoSendStream::Config* send_config,
3104 std::vector<VideoReceiveStream::Config>* receive_configs,
3105 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003106 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003107 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003108 vp9_settings_.numberOfTemporalLayers = 1;
3109 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003110 }
3111
Åsa Perssonff24c042015-12-04 10:58:08 +01003112 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3113 EXPECT_TRUE(vp9_header.flexible_mode);
3114 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3115 if (vp9_header.inter_pic_predicted) {
3116 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003117 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003118 }
3119 }
3120 } test;
3121
stefane74eef12016-01-08 06:47:13 -08003122 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003123}
Peter Boström12996152016-05-14 02:03:18 +02003124#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003125
perkj803d97f2016-11-01 11:45:46 -07003126void VideoSendStreamTest::TestRequestSourceRotateVideo(
3127 bool support_orientation_ext) {
3128 CreateSenderCall(Call::Config(&event_log_));
3129
3130 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003131 CreateSendConfig(1, 0, 0, &transport);
perkj803d97f2016-11-01 11:45:46 -07003132 video_send_config_.rtp.extensions.clear();
3133 if (support_orientation_ext) {
3134 video_send_config_.rtp.extensions.push_back(
3135 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3136 }
3137
3138 CreateVideoStreams();
3139 test::FrameForwarder forwarder;
3140 video_send_stream_->SetSource(
3141 &forwarder, VideoSendStream::DegradationPreference::kBalanced);
3142
3143 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3144 support_orientation_ext);
3145
3146 DestroyStreams();
3147}
3148
3149TEST_F(VideoSendStreamTest,
3150 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3151 TestRequestSourceRotateVideo(false);
3152}
3153
3154TEST_F(VideoSendStreamTest,
3155 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3156 TestRequestSourceRotateVideo(true);
3157}
3158
michaelta3328772016-11-29 09:25:03 -08003159// This test verifies that overhead is removed from the bandwidth estimate by
3160// testing that the maximum possible target payload rate is smaller than the
3161// maximum bandwidth estimate by the overhead rate.
3162TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
3163 test::ScopedFieldTrials override_field_trials(
3164 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3165 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3166 public test::FakeEncoder {
3167 public:
3168 RemoveOverheadFromBandwidthTest()
3169 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3170 FakeEncoder(Clock::GetRealTimeClock()),
3171 call_(nullptr),
3172 max_bitrate_kbps_(0) {}
3173
3174 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
3175 uint32_t frameRate) override {
3176 rtc::CritScope lock(&crit_);
3177 if (max_bitrate_kbps_ < bitrate.get_sum_kbps())
3178 max_bitrate_kbps_ = bitrate.get_sum_kbps();
3179 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3180 }
3181
3182 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3183 call_ = sender_call;
3184 }
3185
3186 void ModifyVideoConfigs(
3187 VideoSendStream::Config* send_config,
3188 std::vector<VideoReceiveStream::Config>* receive_configs,
3189 VideoEncoderConfig* encoder_config) override {
3190 send_config->rtp.max_packet_size = 1200;
3191 send_config->encoder_settings.encoder = this;
3192 EXPECT_FALSE(send_config->rtp.extensions.empty());
3193 }
3194
3195 void PerformTest() override {
3196 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 20);
3197 Call::Config::BitrateConfig bitrate_config;
3198 constexpr int kStartBitrateBps = 50000;
3199 constexpr int kMaxBitrateBps = 60000;
3200 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3201 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
3202 call_->SetBitrateConfig(bitrate_config);
3203
3204 // At a bitrate of 60kbps with a packet size of 1200B video and an
3205 // overhead of 40B per packet video produces 2kbps overhead.
3206 // So with a BWE should reach 58kbps but not 60kbps.
3207 Wait();
3208 {
3209 rtc::CritScope lock(&crit_);
3210 EXPECT_EQ(58u, max_bitrate_kbps_);
3211 }
3212 }
3213
3214 private:
3215 Call* call_;
3216 rtc::CriticalSection crit_;
3217 uint32_t max_bitrate_kbps_ GUARDED_BY(&crit_);
3218 } test;
3219
3220 RunBaseTest(&test);
3221}
3222
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003223} // namespace webrtc