blob: 18bb9b8e127bd18d7ab23b714a8c6920175c60a2 [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_;
sprang867fb522015-08-03 04:38:41 -0700243 }
244
245 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100246 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700247 }
248
249 test::FakeEncoder encoder_;
250 } test;
251
stefane74eef12016-01-08 06:47:13 -0800252 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700253}
254
perkj803d97f2016-11-01 11:45:46 -0700255TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
256 class VideoRotationObserver : public test::SendTest {
257 public:
258 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
259 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
260 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
261 }
262
263 Action OnSendRtp(const uint8_t* packet, size_t length) override {
264 RTPHeader header;
265 EXPECT_TRUE(parser_->Parse(packet, length, &header));
266 EXPECT_TRUE(header.extension.hasVideoRotation);
267 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
268 observation_complete_.Set();
269 return SEND_PACKET;
270 }
271
272 void ModifyVideoConfigs(
273 VideoSendStream::Config* send_config,
274 std::vector<VideoReceiveStream::Config>* receive_configs,
275 VideoEncoderConfig* encoder_config) override {
276 send_config->rtp.extensions.clear();
277 send_config->rtp.extensions.push_back(RtpExtension(
278 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
279 }
280
281 void OnFrameGeneratorCapturerCreated(
282 test::FrameGeneratorCapturer* frame_generator_capturer) override {
283 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
284 }
285
286 void PerformTest() override {
287 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
288 }
289 } test;
290
291 RunBaseTest(&test);
292}
293
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000294class FakeReceiveStatistics : public NullReceiveStatistics {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000295 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000296 FakeReceiveStatistics(uint32_t send_ssrc,
297 uint32_t last_sequence_number,
298 uint32_t cumulative_lost,
299 uint8_t fraction_lost)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000300 : lossy_stats_(new LossyStatistician(last_sequence_number,
301 cumulative_lost,
302 fraction_lost)) {
303 stats_map_[send_ssrc] = lossy_stats_.get();
304 }
305
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000306 StatisticianMap GetActiveStatisticians() const override { return stats_map_; }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000307
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000308 StreamStatistician* GetStatistician(uint32_t ssrc) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000309 return lossy_stats_.get();
310 }
311
312 private:
313 class LossyStatistician : public StreamStatistician {
314 public:
315 LossyStatistician(uint32_t extended_max_sequence_number,
316 uint32_t cumulative_lost,
317 uint8_t fraction_lost) {
318 stats_.fraction_lost = fraction_lost;
319 stats_.cumulative_lost = cumulative_lost;
320 stats_.extended_max_sequence_number = extended_max_sequence_number;
321 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000322 bool GetStatistics(RtcpStatistics* statistics, bool reset) override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000323 *statistics = stats_;
324 return true;
325 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000326 void GetDataCounters(size_t* bytes_received,
327 uint32_t* packets_received) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000328 *bytes_received = 0;
329 *packets_received = 0;
330 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000331 void GetReceiveStreamDataCounters(
332 StreamDataCounters* data_counters) const override {}
333 uint32_t BitrateReceived() const override { return 0; }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000334 bool IsRetransmitOfOldPacket(const RTPHeader& header,
335 int64_t min_rtt) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000336 return false;
337 }
338
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000339 bool IsPacketInOrder(uint16_t sequence_number) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000340 return true;
341 }
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000342
343 RtcpStatistics stats_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000344 };
345
kwiberg27f982b2016-03-01 11:52:33 -0800346 std::unique_ptr<LossyStatistician> lossy_stats_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000347 StatisticianMap stats_map_;
348};
349
brandtre602f0a2016-10-31 03:40:49 -0700350class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100351 public:
brandtre602f0a2016-10-31 03:40:49 -0700352 UlpfecObserver(bool header_extensions_enabled,
brandtr65a1e772016-12-12 01:54:58 -0800353 bool use_nack,
354 bool expect_red,
355 bool expect_ulpfec,
brandtr696c9c62016-12-19 05:47:28 -0800356 const std::string& codec,
357 VideoEncoder* encoder)
brandtr20d45472017-01-02 00:34:27 -0800358 : EndToEndTest(kTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800359 encoder_(encoder),
Peter Boström39593972016-02-15 11:27:15 +0100360 payload_name_(codec),
361 use_nack_(use_nack),
362 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700363 expect_ulpfec_(expect_ulpfec),
brandtr65a1e772016-12-12 01:54:58 -0800364 sent_media_(false),
365 sent_ulpfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800366 header_extensions_enabled_(header_extensions_enabled) {}
Stefan Holmer4654d202015-12-08 09:10:43 +0100367
brandtr20d45472017-01-02 00:34:27 -0800368 // Some of the test cases are expected to time out and thus we are using
369 // a shorter timeout window than the default here.
370 static constexpr size_t kTimeoutMs = 10000;
371
Stefan Holmer4654d202015-12-08 09:10:43 +0100372 private:
373 Action OnSendRtp(const uint8_t* packet, size_t length) override {
374 RTPHeader header;
375 EXPECT_TRUE(parser_->Parse(packet, length, &header));
376
Stefan Holmer4654d202015-12-08 09:10:43 +0100377 int encapsulated_payload_type = -1;
378 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100379 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100380 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
381 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100382 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100383 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
384 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100385 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100386 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100387 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
388 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100389 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
390 length) {
391 // Not padding-only, media received outside of RED.
392 EXPECT_FALSE(expect_red_);
brandtr65a1e772016-12-12 01:54:58 -0800393 sent_media_ = true;
Peter Boström39593972016-02-15 11:27:15 +0100394 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100395 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000396
Stefan Holmer4654d202015-12-08 09:10:43 +0100397 if (header_extensions_enabled_) {
398 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
399 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
400 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
401 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
402 // 24 bits wrap.
403 EXPECT_GT(prev_header_.extension.absoluteSendTime,
404 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000405 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100406 EXPECT_GE(header.extension.absoluteSendTime,
407 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200408 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100409 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
410 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
411 prev_header_.extension.transportSequenceNumber;
412 EXPECT_EQ(1, seq_num_diff);
413 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200414
Stefan Holmer4654d202015-12-08 09:10:43 +0100415 if (encapsulated_payload_type != -1) {
416 if (encapsulated_payload_type ==
417 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700418 EXPECT_TRUE(expect_ulpfec_);
brandtr65a1e772016-12-12 01:54:58 -0800419 sent_ulpfec_ = true;
Stefan Holmer4654d202015-12-08 09:10:43 +0100420 } else {
brandtr65a1e772016-12-12 01:54:58 -0800421 sent_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000422 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000423 }
424
brandtr20d45472017-01-02 00:34:27 -0800425 if (sent_media_ && sent_ulpfec_) {
426 observation_complete_.Set();
Peter Boström39593972016-02-15 11:27:15 +0100427 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000428
Stefan Holmer4654d202015-12-08 09:10:43 +0100429 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000430
Stefan Holmer4654d202015-12-08 09:10:43 +0100431 return SEND_PACKET;
432 }
433
Peter Boström39593972016-02-15 11:27:15 +0100434 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
435 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
436 // Configure some network delay.
437 const int kNetworkDelayMs = 100;
438 FakeNetworkPipe::Config config;
brandtr65a1e772016-12-12 01:54:58 -0800439 config.loss_percent = 5;
Peter Boström39593972016-02-15 11:27:15 +0100440 config.queue_delay_ms = kNetworkDelayMs;
441 return new test::PacketTransport(sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -0700442 test::PacketTransport::kSender,
443 MediaType::VIDEO, config);
Peter Boström39593972016-02-15 11:27:15 +0100444 }
445
stefanff483612015-12-21 03:14:00 -0800446 void ModifyVideoConfigs(
447 VideoSendStream::Config* send_config,
448 std::vector<VideoReceiveStream::Config>* receive_configs,
449 VideoEncoderConfig* encoder_config) override {
Peter Boström39593972016-02-15 11:27:15 +0100450 if (use_nack_) {
451 send_config->rtp.nack.rtp_history_ms =
452 (*receive_configs)[0].rtp.nack.rtp_history_ms =
453 VideoSendStreamTest::kNackRtpHistoryMs;
454 }
brandtr696c9c62016-12-19 05:47:28 -0800455 send_config->encoder_settings.encoder = encoder_;
Peter Boström39593972016-02-15 11:27:15 +0100456 send_config->encoder_settings.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700457 send_config->rtp.ulpfec.red_payload_type =
458 VideoSendStreamTest::kRedPayloadType;
459 send_config->rtp.ulpfec.ulpfec_payload_type =
460 VideoSendStreamTest::kUlpfecPayloadType;
stefanb77c7162017-02-06 06:29:38 -0800461 EXPECT_FALSE(send_config->rtp.extensions.empty());
462 if (!header_extensions_enabled_) {
463 send_config->rtp.extensions.clear();
464 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100465 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700466 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100467 }
brandtrb5f2c3f2016-10-04 23:28:39 -0700468 (*receive_configs)[0].rtp.ulpfec.red_payload_type =
469 send_config->rtp.ulpfec.red_payload_type;
470 (*receive_configs)[0].rtp.ulpfec.ulpfec_payload_type =
471 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100472 }
473
474 void PerformTest() override {
brandtr20d45472017-01-02 00:34:27 -0800475 EXPECT_EQ(expect_ulpfec_, Wait())
476 << "Timed out waiting for ULPFEC and/or media packets.";
Stefan Holmer4654d202015-12-08 09:10:43 +0100477 }
478
brandtr696c9c62016-12-19 05:47:28 -0800479 VideoEncoder* const encoder_;
480 std::string payload_name_;
Peter Boström39593972016-02-15 11:27:15 +0100481 const bool use_nack_;
482 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700483 const bool expect_ulpfec_;
brandtr65a1e772016-12-12 01:54:58 -0800484 bool sent_media_;
485 bool sent_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100486 bool header_extensions_enabled_;
487 RTPHeader prev_header_;
488};
489
brandtre602f0a2016-10-31 03:40:49 -0700490TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800491 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
492 UlpfecObserver test(true, false, true, true, "VP8", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800493 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100494}
495
brandtre602f0a2016-10-31 03:40:49 -0700496TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
brandtr696c9c62016-12-19 05:47:28 -0800497 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
498 UlpfecObserver test(false, false, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100499 RunBaseTest(&test);
500}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000501
Peter Boström39593972016-02-15 11:27:15 +0100502// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
503// since we'll still have to re-request FEC packets, effectively wasting
504// bandwidth since the receiver has to wait for FEC retransmissions to determine
505// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700506TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800507 std::unique_ptr<VideoEncoder> encoder(
508 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
509 UlpfecObserver test(false, true, true, false, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100510 RunBaseTest(&test);
511}
512
513// Without retransmissions FEC for H264 is fine.
brandtre6f98c72016-11-11 03:28:30 -0800514TEST_F(VideoSendStreamTest, DoesUtilizeUlpfecForH264WithoutNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800515 std::unique_ptr<VideoEncoder> encoder(
516 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
517 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100518 RunBaseTest(&test);
519}
520
danilchap9f5b6222017-03-02 06:22:21 -0800521// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
522TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp8WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800523 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
524 UlpfecObserver test(false, true, true, true, "VP8", encoder.get());
Peter Boström39593972016-02-15 11:27:15 +0100525 RunBaseTest(&test);
526}
527
Peter Boström12996152016-05-14 02:03:18 +0200528#if !defined(RTC_DISABLE_VP9)
danilchap9f5b6222017-03-02 06:22:21 -0800529// Disabled as flaky, see https://crbug.com/webrtc/7285 for details.
530TEST_F(VideoSendStreamTest, DISABLED_DoesUtilizeUlpfecForVp9WithNackEnabled) {
brandtr696c9c62016-12-19 05:47:28 -0800531 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
532 UlpfecObserver test(false, true, true, true, "VP9", encoder.get());
stefane74eef12016-01-08 06:47:13 -0800533 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000534}
Peter Boström12996152016-05-14 02:03:18 +0200535#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000536
brandtre78d2662017-01-16 05:57:16 -0800537TEST_F(VideoSendStreamTest, SupportsUlpfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800538 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800539 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800540 UlpfecObserver test(false, false, true, true, "H264", encoder.get());
541 RunBaseTest(&test);
542}
543
brandtr39f97292016-11-16 22:57:50 -0800544// TODO(brandtr): Move these FlexFEC tests when we have created
545// FlexfecSendStream.
546class FlexfecObserver : public test::EndToEndTest {
547 public:
548 FlexfecObserver(bool header_extensions_enabled,
549 bool use_nack,
brandtr696c9c62016-12-19 05:47:28 -0800550 const std::string& codec,
551 VideoEncoder* encoder)
brandtr39f97292016-11-16 22:57:50 -0800552 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
brandtr696c9c62016-12-19 05:47:28 -0800553 encoder_(encoder),
brandtr39f97292016-11-16 22:57:50 -0800554 payload_name_(codec),
555 use_nack_(use_nack),
brandtr39f97292016-11-16 22:57:50 -0800556 sent_media_(false),
557 sent_flexfec_(false),
brandtr696c9c62016-12-19 05:47:28 -0800558 header_extensions_enabled_(header_extensions_enabled) {}
brandtr39f97292016-11-16 22:57:50 -0800559
560 size_t GetNumFlexfecStreams() const override { return 1; }
561
562 private:
563 Action OnSendRtp(const uint8_t* packet, size_t length) override {
564 RTPHeader header;
565 EXPECT_TRUE(parser_->Parse(packet, length, &header));
566
brandtr39f97292016-11-16 22:57:50 -0800567 if (header.payloadType == VideoSendStreamTest::kFlexfecPayloadType) {
568 EXPECT_EQ(VideoSendStreamTest::kFlexfecSendSsrc, header.ssrc);
569 sent_flexfec_ = true;
570 } else {
571 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
572 header.payloadType);
573 EXPECT_EQ(VideoSendStreamTest::kVideoSendSsrcs[0], header.ssrc);
574 sent_media_ = true;
575 }
576
577 if (header_extensions_enabled_) {
578 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
579 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
580 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
581 }
582
brandtr0c5a1542016-11-23 04:42:26 -0800583 if (sent_media_ && sent_flexfec_) {
brandtr39f97292016-11-16 22:57:50 -0800584 observation_complete_.Set();
585 }
586
587 return SEND_PACKET;
588 }
589
590 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
591 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
592 // Therefore we need some network delay.
593 const int kNetworkDelayMs = 100;
594 FakeNetworkPipe::Config config;
brandtrd654a9b2016-12-05 05:38:19 -0800595 config.loss_percent = 5;
brandtr39f97292016-11-16 22:57:50 -0800596 config.queue_delay_ms = kNetworkDelayMs;
597 return new test::PacketTransport(sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -0700598 test::PacketTransport::kSender,
599 MediaType::VIDEO, config);
brandtr39f97292016-11-16 22:57:50 -0800600 }
601
602 void ModifyVideoConfigs(
603 VideoSendStream::Config* send_config,
604 std::vector<VideoReceiveStream::Config>* receive_configs,
605 VideoEncoderConfig* encoder_config) override {
brandtr39f97292016-11-16 22:57:50 -0800606 if (use_nack_) {
607 send_config->rtp.nack.rtp_history_ms =
608 (*receive_configs)[0].rtp.nack.rtp_history_ms =
609 VideoSendStreamTest::kNackRtpHistoryMs;
610 }
brandtr696c9c62016-12-19 05:47:28 -0800611 send_config->encoder_settings.encoder = encoder_;
brandtr39f97292016-11-16 22:57:50 -0800612 send_config->encoder_settings.payload_name = payload_name_;
613 if (header_extensions_enabled_) {
614 send_config->rtp.extensions.push_back(RtpExtension(
615 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
616 send_config->rtp.extensions.push_back(RtpExtension(
617 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
stefanb77c7162017-02-06 06:29:38 -0800618 } else {
619 send_config->rtp.extensions.clear();
brandtr39f97292016-11-16 22:57:50 -0800620 }
621 }
622
623 void PerformTest() override {
624 EXPECT_TRUE(Wait())
625 << "Timed out waiting for FlexFEC and/or media packets.";
626 }
627
brandtr696c9c62016-12-19 05:47:28 -0800628 VideoEncoder* const encoder_;
629 std::string payload_name_;
brandtr39f97292016-11-16 22:57:50 -0800630 const bool use_nack_;
brandtr39f97292016-11-16 22:57:50 -0800631 bool sent_media_;
632 bool sent_flexfec_;
633 bool header_extensions_enabled_;
634};
635
brandtrd654a9b2016-12-05 05:38:19 -0800636TEST_F(VideoSendStreamTest, SupportsFlexfecVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800637 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
638 FlexfecObserver test(false, false, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800639 RunBaseTest(&test);
640}
641
642TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800643 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
644 FlexfecObserver test(false, true, "VP8", encoder.get());
brandtrd654a9b2016-12-05 05:38:19 -0800645 RunBaseTest(&test);
646}
647
brandtr39f97292016-11-16 22:57:50 -0800648TEST_F(VideoSendStreamTest, SupportsFlexfecWithRtpExtensionsVp8) {
brandtr696c9c62016-12-19 05:47:28 -0800649 std::unique_ptr<VideoEncoder> encoder(VP8Encoder::Create());
650 FlexfecObserver test(true, false, "VP8", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800651 RunBaseTest(&test);
652}
653
brandtr39f97292016-11-16 22:57:50 -0800654#if !defined(RTC_DISABLE_VP9)
brandtrd654a9b2016-12-05 05:38:19 -0800655TEST_F(VideoSendStreamTest, SupportsFlexfecVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800656 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
657 FlexfecObserver test(false, false, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800658 RunBaseTest(&test);
659}
660
brandtrd654a9b2016-12-05 05:38:19 -0800661TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackVp9) {
brandtr696c9c62016-12-19 05:47:28 -0800662 std::unique_ptr<VideoEncoder> encoder(VP9Encoder::Create());
663 FlexfecObserver test(false, true, "VP9", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800664 RunBaseTest(&test);
665}
666#endif // defined(RTC_DISABLE_VP9)
667
brandtrd654a9b2016-12-05 05:38:19 -0800668TEST_F(VideoSendStreamTest, SupportsFlexfecH264) {
brandtr696c9c62016-12-19 05:47:28 -0800669 std::unique_ptr<VideoEncoder> encoder(
670 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
671 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800672 RunBaseTest(&test);
673}
674
brandtrd654a9b2016-12-05 05:38:19 -0800675TEST_F(VideoSendStreamTest, SupportsFlexfecWithNackH264) {
brandtr696c9c62016-12-19 05:47:28 -0800676 std::unique_ptr<VideoEncoder> encoder(
677 new test::FakeH264Encoder(Clock::GetRealTimeClock()));
678 FlexfecObserver test(false, true, "H264", encoder.get());
679 RunBaseTest(&test);
680}
681
brandtre78d2662017-01-16 05:57:16 -0800682TEST_F(VideoSendStreamTest, SupportsFlexfecWithMultithreadedH264) {
brandtr696c9c62016-12-19 05:47:28 -0800683 std::unique_ptr<VideoEncoder> encoder(
brandtre78d2662017-01-16 05:57:16 -0800684 new test::MultithreadedFakeH264Encoder(Clock::GetRealTimeClock()));
brandtr696c9c62016-12-19 05:47:28 -0800685 FlexfecObserver test(false, false, "H264", encoder.get());
brandtr39f97292016-11-16 22:57:50 -0800686 RunBaseTest(&test);
687}
688
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000689void VideoSendStreamTest::TestNackRetransmission(
690 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000691 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000692 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000693 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000694 explicit NackObserver(uint32_t retransmit_ssrc,
695 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000696 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000697 send_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000698 retransmit_ssrc_(retransmit_ssrc),
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000699 retransmit_payload_type_(retransmit_payload_type),
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000700 nacked_sequence_number_(-1) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000701 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000702
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000703 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000704 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000705 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000706 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000707
708 // Nack second packet after receiving the third one.
709 if (++send_count_ == 3) {
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000710 uint16_t nack_sequence_number = header.sequenceNumber - 1;
711 nacked_sequence_number_ = nack_sequence_number;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000712 NullReceiveStatistics null_stats;
Peter Boströmac547a62015-09-17 23:03:57 +0200713 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), &null_stats,
terelius429c3452016-01-21 05:42:04 -0800714 nullptr, nullptr, transport_adapter_.get());
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000715
pbosda903ea2015-10-02 02:36:56 -0700716 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100717 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000718
719 RTCPSender::FeedbackState feedback_state;
720
721 EXPECT_EQ(0,
722 rtcp_sender.SendRTCP(
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000723 feedback_state, kRtcpNack, 1, &nack_sequence_number));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000724 }
725
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000726 uint16_t sequence_number = header.sequenceNumber;
727
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000728 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100729 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
730 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000731 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000732 const uint8_t* rtx_header = packet + header.headerLength;
733 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
734 }
735
736 if (sequence_number == nacked_sequence_number_) {
737 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000738 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
Peter Boström5811a392015-12-10 13:02:50 +0100739 observation_complete_.Set();
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000740 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000741
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000742 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000743 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000744
stefanff483612015-12-21 03:14:00 -0800745 void ModifyVideoConfigs(
746 VideoSendStream::Config* send_config,
747 std::vector<VideoReceiveStream::Config>* receive_configs,
748 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700749 transport_adapter_.reset(
750 new internal::TransportAdapter(send_config->send_transport));
751 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000752 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000753 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100754 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000755 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
756 }
757
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000758 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100759 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000760 }
761
kwiberg27f982b2016-03-01 11:52:33 -0800762 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000763 int send_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000764 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000765 uint8_t retransmit_payload_type_;
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000766 int nacked_sequence_number_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000767 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000768
stefane74eef12016-01-08 06:47:13 -0800769 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000770}
771
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000772TEST_F(VideoSendStreamTest, RetransmitsNack) {
773 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100774 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000775}
776
777TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
778 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000779 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000780}
781
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000782void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
783 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000784 // Use a fake encoder to output a frame of every size in the range [90, 290],
785 // for each size making sure that the exact number of payload bytes received
786 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000787 static const size_t kMaxPacketSize = 128;
788 static const size_t start = 90;
789 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000790
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000791 // Observer that verifies that the expected number of packets and bytes
792 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000793 class FrameFragmentationTest : public test::SendTest,
794 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000795 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000796 FrameFragmentationTest(size_t max_packet_size,
797 size_t start_size,
798 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000799 bool test_generic_packetization,
800 bool use_fec)
801 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000802 encoder_(stop),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000803 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000804 stop_size_(stop_size),
805 test_generic_packetization_(test_generic_packetization),
806 use_fec_(use_fec),
807 packet_count_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000808 accumulated_size_(0),
809 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000810 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000811 current_size_rtp_(start_size),
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000812 current_size_frame_(static_cast<int32_t>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000813 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000814 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700815 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000816 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000817
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000818 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000819 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000820 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000821 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000822 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000823
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000824 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000825
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000826 if (use_fec_) {
827 uint8_t payload_type = packet[header.headerLength];
828 bool is_fec = header.payloadType == kRedPayloadType &&
829 payload_type == kUlpfecPayloadType;
830 if (is_fec) {
831 fec_packet_received_ = true;
832 return SEND_PACKET;
833 }
834 }
835
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000836 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000837
838 if (use_fec_)
839 TriggerLossReport(header);
840
841 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200842 size_t overhead = header.headerLength + header.paddingLength;
843 // Only remove payload header and RED header if the packet actually
844 // contains payload.
845 if (length > overhead) {
846 overhead += (1 /* Generic header */);
847 if (use_fec_)
848 overhead += 1; // RED for FEC header.
849 }
850 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000851 accumulated_payload_ += length - overhead;
852 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000853
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000854 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000855 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000856 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
857 // With FEC enabled, frame size is incremented asynchronously, so
858 // "old" frames one byte too small may arrive. Accept, but don't
859 // increase expected frame size.
860 accumulated_size_ = 0;
861 accumulated_payload_ = 0;
862 return SEND_PACKET;
863 }
864
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000865 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000866 if (test_generic_packetization_) {
867 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
868 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000869
870 // Last packet of frame; reset counters.
871 accumulated_size_ = 0;
872 accumulated_payload_ = 0;
873 if (current_size_rtp_ == stop_size_) {
874 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +0100875 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000876 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000877 // Increase next expected frame size. If testing with FEC, make sure
878 // a FEC packet has been received for this frame size before
879 // proceeding, to make sure that redundancy packets don't exceed
880 // size limit.
881 if (!use_fec_) {
882 ++current_size_rtp_;
883 } else if (fec_packet_received_) {
884 fec_packet_received_ = false;
885 ++current_size_rtp_;
886 ++current_size_frame_;
887 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000888 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000889 }
890
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000891 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000892 }
893
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000894 void TriggerLossReport(const RTPHeader& header) {
895 // Send lossy receive reports to trigger FEC enabling.
896 if (packet_count_++ % 2 != 0) {
897 // Receive statistics reporting having lost 50% of the packets.
898 FakeReceiveStatistics lossy_receive_stats(
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100899 kVideoSendSsrcs[0], header.sequenceNumber, packet_count_ / 2, 127);
Peter Boströmac547a62015-09-17 23:03:57 +0200900 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -0800901 &lossy_receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -0700902 transport_adapter_.get());
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000903
pbosda903ea2015-10-02 02:36:56 -0700904 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100905 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000906
907 RTCPSender::FeedbackState feedback_state;
908
909 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
910 }
911 }
912
nisseef8b61e2016-04-29 06:09:15 -0700913 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000914 // Increase frame size for next encoded frame, in the context of the
915 // encoder thread.
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000916 if (!use_fec_ &&
917 current_size_frame_.Value() < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000918 ++current_size_frame_;
919 }
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000920 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_.Value()));
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000921 }
922
Stefan Holmere5904162015-03-26 11:11:06 +0100923 Call::Config GetSenderCallConfig() override {
skvlad11a9cbf2016-10-07 11:53:05 -0700924 Call::Config config(&event_log_);
Stefan Holmere5904162015-03-26 11:11:06 +0100925 const int kMinBitrateBps = 30000;
926 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
927 return config;
928 }
929
stefanff483612015-12-21 03:14:00 -0800930 void ModifyVideoConfigs(
931 VideoSendStream::Config* send_config,
932 std::vector<VideoReceiveStream::Config>* receive_configs,
933 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700934 transport_adapter_.reset(
935 new internal::TransportAdapter(send_config->send_transport));
936 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000937 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -0700938 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
939 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000940 }
941
942 if (!test_generic_packetization_)
943 send_config->encoder_settings.payload_name = "VP8";
944
945 send_config->encoder_settings.encoder = &encoder_;
946 send_config->rtp.max_packet_size = kMaxPacketSize;
947 send_config->post_encode_callback = this;
948
Erik Språng95261872015-04-10 11:58:49 +0200949 // Make sure there is at least one extension header, to make the RTP
950 // header larger than the base length of 12 bytes.
951 EXPECT_FALSE(send_config->rtp.extensions.empty());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000952 }
953
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000954 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100955 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000956 }
957
kwiberg27f982b2016-03-01 11:52:33 -0800958 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000959 test::ConfigurableFrameSizeEncoder encoder_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000960
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000961 const size_t max_packet_size_;
962 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000963 const bool test_generic_packetization_;
964 const bool use_fec_;
965
966 uint32_t packet_count_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000967 size_t accumulated_size_;
968 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000969 bool fec_packet_received_;
970
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000971 size_t current_size_rtp_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000972 Atomic32 current_size_frame_;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000973 };
974
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000975 // Don't auto increment if FEC is used; continue sending frame size until
976 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000977 FrameFragmentationTest test(
978 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000979
stefane74eef12016-01-08 06:47:13 -0800980 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000981}
982
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000983// TODO(sprang): Is there any way of speeding up these tests?
984TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
985 TestPacketFragmentationSize(kGeneric, false);
986}
987
988TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
989 TestPacketFragmentationSize(kGeneric, true);
990}
991
992TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
993 TestPacketFragmentationSize(kVP8, false);
994}
995
996TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
997 TestPacketFragmentationSize(kVP8, true);
998}
999
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001000// The test will go through a number of phases.
1001// 1. Start sending packets.
1002// 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 +00001003// suspend the stream.
1004// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001005// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001006// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001007// When the stream is detected again, and the stats show that the stream
1008// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001009TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
1010 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001011
nissed30a1112016-04-18 05:15:22 -07001012 class RembObserver : public test::SendTest,
1013 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001014 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001015 RembObserver()
1016 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001017 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +02001018 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001019 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001020 rtp_count_(0),
1021 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001022 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001023 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +02001024 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001025
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001026 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001027 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001028 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001029 ++rtp_count_;
1030 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001031 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001032 last_sequence_number_ = header.sequenceNumber;
1033
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001034 if (test_state_ == kBeforeSuspend) {
1035 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001036 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001037 test_state_ = kDuringSuspend;
1038 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001039 if (header.paddingLength == 0) {
1040 // Received non-padding packet during suspension period. Reset the
1041 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001042 suspended_frame_count_ = 0;
1043 }
stefanf116bd02015-10-27 08:29:42 -07001044 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001045 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001046 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001047 // Non-padding packet observed. Test is almost complete. Will just
1048 // have to wait for the stats to change.
1049 test_state_ = kWaitingForStats;
1050 }
stefanf116bd02015-10-27 08:29:42 -07001051 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001052 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001053 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001054 if (stats.suspended == false) {
1055 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +01001056 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +00001057 }
stefanf116bd02015-10-27 08:29:42 -07001058 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001059 }
1060
stefan@webrtc.org69969e22013-11-15 12:32:15 +00001061 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001062 }
1063
perkj26091b12016-09-01 01:17:40 -07001064 // This method implements the rtc::VideoSinkInterface. This is called when
1065 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -07001066 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001067 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001068 if (test_state_ == kDuringSuspend &&
1069 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001070 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +00001071 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001072 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001073 test_state_ = kWaitingForPacket;
1074 }
1075 }
1076
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001077 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001078 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001079 low_remb_bps_ = value;
1080 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001081
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001082 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +02001083 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001084 high_remb_bps_ = value;
1085 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +00001086
stefanff483612015-12-21 03:14:00 -08001087 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001088 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001089 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001090 stream_ = send_stream;
1091 }
1092
stefanff483612015-12-21 03:14:00 -08001093 void ModifyVideoConfigs(
1094 VideoSendStream::Config* send_config,
1095 std::vector<VideoReceiveStream::Config>* receive_configs,
1096 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001097 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -07001098 transport_adapter_.reset(
1099 new internal::TransportAdapter(send_config->send_transport));
1100 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001101 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001102 send_config->pre_encode_callback = this;
1103 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -07001104 int min_bitrate_bps =
1105 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001106 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +02001107 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -07001108 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001109 min_bitrate_bps + threshold_window + 5000);
1110 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
1111 }
1112
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001113 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001114 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001115 }
1116
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001117 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +00001118 kBeforeSuspend,
1119 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001120 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +00001121 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001122 };
1123
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001124 virtual void SendRtcpFeedback(int remb_value)
1125 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001126 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
1127 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -08001128 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -07001129 transport_adapter_.get());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001130
pbosda903ea2015-10-02 02:36:56 -07001131 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001132 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001133 if (remb_value > 0) {
1134 rtcp_sender.SetREMBStatus(true);
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001135 rtcp_sender.SetREMBData(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001136 }
1137 RTCPSender::FeedbackState feedback_state;
1138 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
1139 }
1140
kwiberg27f982b2016-03-01 11:52:33 -08001141 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001142 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001143 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001144
Peter Boströmf2f82832015-05-01 13:00:41 +02001145 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001146 TestState test_state_ GUARDED_BY(crit_);
1147 int rtp_count_ GUARDED_BY(crit_);
1148 int last_sequence_number_ GUARDED_BY(crit_);
1149 int suspended_frame_count_ GUARDED_BY(crit_);
1150 int low_remb_bps_ GUARDED_BY(crit_);
1151 int high_remb_bps_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001152 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001153
stefane74eef12016-01-08 06:47:13 -08001154 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001155}
1156
perkj71ee44c2016-06-15 00:47:53 -07001157// This test that padding stops being send after a while if the Camera stops
1158// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001159TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001160 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001161 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001162 NoPaddingWhenVideoIsMuted()
1163 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001164 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001165 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001166 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +00001167 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001168
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001169 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001170 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001171 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001172 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001173
1174 RTPHeader header;
1175 parser_->Parse(packet, length, &header);
1176 const bool only_padding =
1177 header.headerLength + header.paddingLength == length;
1178
1179 if (test_state_ == kBeforeStopCapture) {
1180 capturer_->Stop();
1181 test_state_ = kWaitingForPadding;
1182 } else if (test_state_ == kWaitingForPadding && only_padding) {
1183 test_state_ = kWaitingForNoPackets;
1184 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1185 only_padding) {
1186 observation_complete_.Set();
1187 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001188 return SEND_PACKET;
1189 }
1190
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001191 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001192 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001193 const int kNoPacketsThresholdMs = 2000;
1194 if (test_state_ == kWaitingForNoPackets &&
1195 (last_packet_time_ms_ > 0 &&
1196 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1197 kNoPacketsThresholdMs)) {
1198 capturer_->Start();
1199 test_state_ = kWaitingForPaddingAfterCameraRestart;
1200 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001201 return SEND_PACKET;
1202 }
1203
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001204 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001205
nisseef8b61e2016-04-29 06:09:15 -07001206 void OnFrameGeneratorCapturerCreated(
1207 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001208 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001209 capturer_ = frame_generator_capturer;
1210 }
1211
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001212 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001213 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001214 << "Timed out while waiting for RTP packets to stop being sent.";
1215 }
1216
perkj71ee44c2016-06-15 00:47:53 -07001217 enum TestState {
1218 kBeforeStopCapture,
1219 kWaitingForPadding,
1220 kWaitingForNoPackets,
1221 kWaitingForPaddingAfterCameraRestart
1222 };
1223
1224 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001225 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001226 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001227 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001228 int64_t last_packet_time_ms_ GUARDED_BY(crit_);
1229 test::FrameGeneratorCapturer* capturer_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001230 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001231
stefane74eef12016-01-08 06:47:13 -08001232 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001233}
1234
isheriffcc5903e2016-10-04 08:29:38 -07001235TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1236 const int kCapacityKbps = 10000; // 10 Mbps
1237 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1238 public:
1239 PaddingIsPrimarilyRetransmissions()
1240 : EndToEndTest(kDefaultTimeoutMs),
1241 clock_(Clock::GetRealTimeClock()),
1242 padding_length_(0),
1243 total_length_(0),
1244 call_(nullptr) {}
1245
1246 private:
1247 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1248 call_ = sender_call;
1249 }
1250
1251 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1252 rtc::CritScope lock(&crit_);
1253
1254 RTPHeader header;
1255 parser_->Parse(packet, length, &header);
1256 padding_length_ += header.paddingLength;
1257 total_length_ += length;
1258 return SEND_PACKET;
1259 }
1260
1261 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
1262 const int kNetworkDelayMs = 50;
1263 FakeNetworkPipe::Config config;
1264 config.loss_percent = 10;
1265 config.link_capacity_kbps = kCapacityKbps;
1266 config.queue_delay_ms = kNetworkDelayMs;
1267 return new test::PacketTransport(sender_call, this,
nissee5ad5ca2017-03-29 23:57:43 -07001268 test::PacketTransport::kSender,
1269 MediaType::VIDEO, config);
isheriffcc5903e2016-10-04 08:29:38 -07001270 }
1271
1272 void ModifyVideoConfigs(
1273 VideoSendStream::Config* send_config,
1274 std::vector<VideoReceiveStream::Config>* receive_configs,
1275 VideoEncoderConfig* encoder_config) override {
isheriffcc5903e2016-10-04 08:29:38 -07001276 // Turn on RTX.
1277 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1278 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
isheriffcc5903e2016-10-04 08:29:38 -07001279 }
1280
1281 void PerformTest() override {
1282 // TODO(isheriff): Some platforms do not ramp up as expected to full
1283 // capacity due to packet scheduling delays. Fix that before getting
1284 // rid of this.
1285 SleepMs(5000);
1286 {
1287 rtc::CritScope lock(&crit_);
1288 // Expect padding to be a small percentage of total bytes sent.
1289 EXPECT_LT(padding_length_, .1 * total_length_);
1290 }
1291 }
1292
1293 rtc::CriticalSection crit_;
1294 Clock* const clock_;
1295 size_t padding_length_ GUARDED_BY(crit_);
1296 size_t total_length_ GUARDED_BY(crit_);
1297 Call* call_;
1298 } test;
1299
1300 RunBaseTest(&test);
1301}
1302
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001303// This test first observes "high" bitrate use at which point it sends a REMB to
1304// indicate that it should be lowered significantly. The test then observes that
1305// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1306// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001307//
1308// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1309// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001310TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1311 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001312 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001313 static const int kRembBitrateBps = 80000;
1314 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001315 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001316 public:
1317 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001318 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001319 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1320 stream_(nullptr),
1321 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001322
1323 private:
nisseef8b61e2016-04-29 06:09:15 -07001324 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001325 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001326 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001327
1328 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001329 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001330 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001331 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001332 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001333 if (!stats.substreams.empty()) {
1334 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001335 int total_bitrate_bps =
1336 stats.substreams.begin()->second.total_bitrate_bps;
1337 test::PrintResult("bitrate_stats_",
1338 "min_transmit_bitrate_low_remb",
1339 "bitrate_bps",
1340 static_cast<size_t>(total_bitrate_bps),
1341 "bps",
1342 false);
1343 if (total_bitrate_bps > kHighBitrateBps) {
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001344 rtp_rtcp_->SetREMBData(kRembBitrateBps,
1345 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001346 rtp_rtcp_->Process();
1347 bitrate_capped_ = true;
1348 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001349 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001350 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001351 }
1352 }
stefanf116bd02015-10-27 08:29:42 -07001353 // Packets don't have to be delivered since the test is the receiver.
1354 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001355 }
1356
stefanff483612015-12-21 03:14:00 -08001357 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001358 VideoSendStream* send_stream,
1359 const std::vector<VideoReceiveStream*>& receive_streams) override {
1360 stream_ = send_stream;
1361 RtpRtcp::Configuration config;
1362 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001363 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001364 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
1365 rtp_rtcp_->SetREMBStatus(true);
1366 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001367 }
1368
stefanff483612015-12-21 03:14:00 -08001369 void ModifyVideoConfigs(
1370 VideoSendStream::Config* send_config,
1371 std::vector<VideoReceiveStream::Config>* receive_configs,
1372 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001373 feedback_transport_.reset(
1374 new internal::TransportAdapter(send_config->send_transport));
1375 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001376 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001377 }
1378
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001379 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001380 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001381 << "Timeout while waiting for low bitrate stats after REMB.";
1382 }
1383
kwiberg27f982b2016-03-01 11:52:33 -08001384 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1385 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001386 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001387 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001388 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001389 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001390
stefane74eef12016-01-08 06:47:13 -08001391 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001392}
1393
Stefan Holmer280de9e2016-09-30 10:06:51 +02001394TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1395 static const int kStartBitrateBps = 300000;
1396 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001397 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001398 class ChangingNetworkRouteTest : public test::EndToEndTest {
1399 public:
Stefan Holmerbe402962016-07-08 16:16:41 +02001400 ChangingNetworkRouteTest()
Stefan Holmer280de9e2016-09-30 10:06:51 +02001401 : EndToEndTest(test::CallTest::kDefaultTimeoutMs), call_(nullptr) {
1402 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1403 kRtpExtensionTransportSequenceNumber, kExtensionId));
1404 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001405
1406 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1407 call_ = sender_call;
1408 }
1409
Stefan Holmer280de9e2016-09-30 10:06:51 +02001410 void ModifyVideoConfigs(
1411 VideoSendStream::Config* send_config,
1412 std::vector<VideoReceiveStream::Config>* receive_configs,
1413 VideoEncoderConfig* encoder_config) override {
1414 send_config->rtp.extensions.clear();
1415 send_config->rtp.extensions.push_back(RtpExtension(
1416 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1417 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1418 (*receive_configs)[0].rtp.transport_cc = true;
1419 }
1420
1421 void ModifyAudioConfigs(
1422 AudioSendStream::Config* send_config,
1423 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1424 send_config->rtp.extensions.clear();
1425 send_config->rtp.extensions.push_back(RtpExtension(
1426 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1427 (*receive_configs)[0].rtp.extensions.clear();
1428 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1429 (*receive_configs)[0].rtp.transport_cc = true;
1430 }
1431
Stefan Holmerbe402962016-07-08 16:16:41 +02001432 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1433 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1434 observation_complete_.Set();
1435 }
1436
1437 return SEND_PACKET;
1438 }
1439
1440 void PerformTest() override {
1441 rtc::NetworkRoute new_route(true, 10, 20, -1);
1442 call_->OnNetworkRouteChanged("transport", new_route);
1443 Call::Config::BitrateConfig bitrate_config;
1444 bitrate_config.start_bitrate_bps = kStartBitrateBps;
1445 call_->SetBitrateConfig(bitrate_config);
1446 EXPECT_TRUE(Wait())
1447 << "Timed out while waiting for start bitrate to be exceeded.";
1448
1449 bitrate_config.start_bitrate_bps = -1;
1450 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
1451 call_->SetBitrateConfig(bitrate_config);
1452 // TODO(holmer): We should set the last sent packet id here and verify
1453 // that we correctly ignore any packet loss reported prior to that id.
1454 ++new_route.local_network_id;
1455 call_->OnNetworkRouteChanged("transport", new_route);
stefan01bbc3c2016-10-25 04:19:48 -07001456 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
Stefan Holmerbe402962016-07-08 16:16:41 +02001457 }
1458
1459 private:
1460 Call* call_;
1461 } test;
1462
1463 RunBaseTest(&test);
1464}
1465
michaelt79e05882016-11-08 02:50:09 -08001466TEST_F(VideoSendStreamTest, ChangingTransportOverhead) {
1467 class ChangingTransportOverheadTest : public test::EndToEndTest {
1468 public:
1469 ChangingTransportOverheadTest()
1470 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
1471 call_(nullptr),
Erik Språng08127a92016-11-16 16:41:30 +01001472 packets_sent_(0),
1473 transport_overhead_(0) {}
michaelt79e05882016-11-08 02:50:09 -08001474
1475 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1476 call_ = sender_call;
1477 }
1478
1479 Action OnSendRtp(const uint8_t* packet, size_t length) override {
michaelta3328772016-11-29 09:25:03 -08001480 EXPECT_LE(length, kMaxRtpPacketSize);
sprang21253fc2017-02-27 03:35:47 -08001481 rtc::CritScope cs(&lock_);
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());
sprang21253fc2017-02-27 03:35:47 -08001500 {
1501 rtc::CritScope cs(&lock_);
1502 packets_sent_ = 0;
1503 }
michaelta3328772016-11-29 09:25:03 -08001504 transport_overhead_ = 500;
michaelt79e05882016-11-08 02:50:09 -08001505 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO,
1506 transport_overhead_);
1507 EXPECT_TRUE(Wait());
1508 }
1509
1510 private:
1511 Call* call_;
sprang21253fc2017-02-27 03:35:47 -08001512 rtc::CriticalSection lock_;
1513 int packets_sent_ GUARDED_BY(lock_);
michaelt79e05882016-11-08 02:50:09 -08001514 int transport_overhead_;
michaelta3328772016-11-29 09:25:03 -08001515 const size_t kMaxRtpPacketSize = 1000;
michaelt79e05882016-11-08 02:50:09 -08001516 } test;
1517
1518 RunBaseTest(&test);
1519}
1520
sprangf24a0642017-02-28 13:23:26 -08001521// Test class takes takes as argument a switch selecting if type switch should
1522// occur and a function pointer to reset the send stream. This is necessary
1523// since you cannot change the content type of a VideoSendStream, you need to
1524// recreate it. Stopping and recreating the stream can only be done on the main
1525// thread and in the context of VideoSendStreamTest (not BaseTest).
1526template <typename T>
sprang9c0b5512016-07-06 00:54:28 -07001527class MaxPaddingSetTest : public test::SendTest {
1528 public:
1529 static const uint32_t kMinTransmitBitrateBps = 400000;
1530 static const uint32_t kActualEncodeBitrateBps = 40000;
1531 static const uint32_t kMinPacketsToSend = 50;
1532
sprangf24a0642017-02-28 13:23:26 -08001533 explicit MaxPaddingSetTest(bool test_switch_content_type, T* stream_reset_fun)
sprang9c0b5512016-07-06 00:54:28 -07001534 : SendTest(test::CallTest::kDefaultTimeoutMs),
sprangf24a0642017-02-28 13:23:26 -08001535 content_switch_event_(false, false),
sprang9c0b5512016-07-06 00:54:28 -07001536 call_(nullptr),
1537 send_stream_(nullptr),
sprangf24a0642017-02-28 13:23:26 -08001538 send_stream_config_(nullptr),
sprang9c0b5512016-07-06 00:54:28 -07001539 packets_sent_(0),
sprangf24a0642017-02-28 13:23:26 -08001540 running_without_padding_(test_switch_content_type),
tommi39e12892017-03-13 05:15:14 -07001541 stream_resetter_(stream_reset_fun) {
1542 RTC_DCHECK(stream_resetter_);
1543 }
sprang9c0b5512016-07-06 00:54:28 -07001544
1545 void OnVideoStreamsCreated(
1546 VideoSendStream* send_stream,
1547 const std::vector<VideoReceiveStream*>& receive_streams) override {
sprangf24a0642017-02-28 13:23:26 -08001548 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001549 send_stream_ = send_stream;
1550 }
1551
1552 void ModifyVideoConfigs(
1553 VideoSendStream::Config* send_config,
1554 std::vector<VideoReceiveStream::Config>* receive_configs,
1555 VideoEncoderConfig* encoder_config) override {
kwibergaf476c72016-11-28 15:21:39 -08001556 RTC_DCHECK_EQ(1, encoder_config->number_of_streams);
sprangf24a0642017-02-28 13:23:26 -08001557 if (RunningWithoutPadding()) {
sprang9c0b5512016-07-06 00:54:28 -07001558 encoder_config->min_transmit_bitrate_bps = 0;
1559 encoder_config->content_type =
1560 VideoEncoderConfig::ContentType::kRealtimeVideo;
1561 } else {
1562 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1563 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1564 }
sprangf24a0642017-02-28 13:23:26 -08001565 send_stream_config_ = send_config->Copy();
perkj26091b12016-09-01 01:17:40 -07001566 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001567 }
1568
1569 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1570 call_ = sender_call;
1571 }
1572
1573 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1574 rtc::CritScope lock(&crit_);
sprang9c0b5512016-07-06 00:54:28 -07001575 if (running_without_padding_)
1576 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1577
1578 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1579 // we have reliable data.
1580 if (++packets_sent_ < kMinPacketsToSend)
1581 return SEND_PACKET;
1582
1583 if (running_without_padding_) {
1584 // We've sent kMinPacketsToSend packets with default configuration, switch
1585 // to enabling screen content and setting min transmit bitrate.
sprangf24a0642017-02-28 13:23:26 -08001586 // Note that we need to recreate the stream if changing content type.
sprang9c0b5512016-07-06 00:54:28 -07001587 packets_sent_ = 0;
1588 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1589 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
sprang9c0b5512016-07-06 00:54:28 -07001590 running_without_padding_ = false;
sprangf24a0642017-02-28 13:23:26 -08001591 content_switch_event_.Set();
sprang9c0b5512016-07-06 00:54:28 -07001592 return SEND_PACKET;
1593 }
1594
1595 // Make sure the pacer has been configured with a min transmit bitrate.
1596 if (call_->GetStats().max_padding_bitrate_bps > 0)
1597 observation_complete_.Set();
1598
1599 return SEND_PACKET;
1600 }
1601
1602 void PerformTest() override {
sprangf24a0642017-02-28 13:23:26 -08001603 if (RunningWithoutPadding()) {
1604 ASSERT_TRUE(
1605 content_switch_event_.Wait(test::CallTest::kDefaultTimeoutMs));
sprangf24a0642017-02-28 13:23:26 -08001606 (*stream_resetter_)(send_stream_config_, encoder_config_);
1607 }
1608
sprang9c0b5512016-07-06 00:54:28 -07001609 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1610 }
1611
1612 private:
sprangf24a0642017-02-28 13:23:26 -08001613 bool RunningWithoutPadding() const {
1614 rtc::CritScope lock(&crit_);
1615 return running_without_padding_;
1616 }
1617
sprang9c0b5512016-07-06 00:54:28 -07001618 rtc::CriticalSection crit_;
sprangf24a0642017-02-28 13:23:26 -08001619 rtc::Event content_switch_event_;
sprang9c0b5512016-07-06 00:54:28 -07001620 Call* call_;
sprangf24a0642017-02-28 13:23:26 -08001621 VideoSendStream* send_stream_ GUARDED_BY(crit_);
1622 VideoSendStream::Config send_stream_config_;
sprang9c0b5512016-07-06 00:54:28 -07001623 VideoEncoderConfig encoder_config_;
1624 uint32_t packets_sent_ GUARDED_BY(crit_);
1625 bool running_without_padding_;
sprangf24a0642017-02-28 13:23:26 -08001626 T* const stream_resetter_;
sprang9c0b5512016-07-06 00:54:28 -07001627};
1628
1629TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
sprangf24a0642017-02-28 13:23:26 -08001630 auto reset_fun = [](const VideoSendStream::Config& send_stream_config,
1631 const VideoEncoderConfig& encoder_config) {};
1632 MaxPaddingSetTest<decltype(reset_fun)> test(false, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001633 RunBaseTest(&test);
1634}
1635
1636TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
sprangf24a0642017-02-28 13:23:26 -08001637 // Function for removing and recreating the send stream with a new config.
1638 auto reset_fun = [this](const VideoSendStream::Config& send_stream_config,
1639 const VideoEncoderConfig& encoder_config) {
1640 Stop();
1641 sender_call_->DestroyVideoSendStream(video_send_stream_);
1642 video_send_config_ = send_stream_config.Copy();
1643 video_encoder_config_ = encoder_config.Copy();
1644 video_send_stream_ = sender_call_->CreateVideoSendStream(
1645 video_send_config_.Copy(), video_encoder_config_.Copy());
1646 video_send_stream_->SetSource(
1647 frame_generator_capturer_.get(),
1648 VideoSendStream::DegradationPreference::kMaintainResolution);
1649 Start();
1650 };
1651 MaxPaddingSetTest<decltype(reset_fun)> test(true, &reset_fun);
sprang9c0b5512016-07-06 00:54:28 -07001652 RunBaseTest(&test);
1653}
1654
perkjfa10b552016-10-02 23:45:26 -07001655// This test verifies that new frame sizes reconfigures encoders even though not
1656// (yet) sending. The purpose of this is to permit encoding as quickly as
1657// possible once we start sending. Likely the frames being input are from the
1658// same source that will be sent later, which just means that we're ready
1659// earlier.
1660TEST_F(VideoSendStreamTest,
1661 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1662 class EncoderObserver : public test::FakeEncoder {
1663 public:
1664 EncoderObserver()
1665 : FakeEncoder(Clock::GetRealTimeClock()),
1666 init_encode_called_(false, false),
1667 number_of_initializations_(0),
1668 last_initialized_frame_width_(0),
1669 last_initialized_frame_height_(0) {}
1670
1671 void WaitForResolution(int width, int height) {
1672 {
1673 rtc::CritScope lock(&crit_);
1674 if (last_initialized_frame_width_ == width &&
1675 last_initialized_frame_height_ == height) {
1676 return;
1677 }
1678 }
Erik Språng08127a92016-11-16 16:41:30 +01001679 EXPECT_TRUE(
1680 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
perkjfa10b552016-10-02 23:45:26 -07001681 {
1682 rtc::CritScope lock(&crit_);
1683 EXPECT_EQ(width, last_initialized_frame_width_);
1684 EXPECT_EQ(height, last_initialized_frame_height_);
1685 }
1686 }
1687
1688 private:
1689 int32_t InitEncode(const VideoCodec* config,
1690 int32_t number_of_cores,
1691 size_t max_payload_size) override {
1692 rtc::CritScope lock(&crit_);
1693 last_initialized_frame_width_ = config->width;
1694 last_initialized_frame_height_ = config->height;
1695 ++number_of_initializations_;
Erik Språng08127a92016-11-16 16:41:30 +01001696 init_encode_called_.Set();
perkjfa10b552016-10-02 23:45:26 -07001697 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1698 }
1699
1700 int32_t Encode(const VideoFrame& input_image,
1701 const CodecSpecificInfo* codec_specific_info,
1702 const std::vector<FrameType>* frame_types) override {
1703 ADD_FAILURE()
1704 << "Unexpected Encode call since the send stream is not started";
1705 return 0;
1706 }
1707
1708 rtc::CriticalSection crit_;
1709 rtc::Event init_encode_called_;
1710 size_t number_of_initializations_ GUARDED_BY(&crit_);
1711 int last_initialized_frame_width_ GUARDED_BY(&crit_);
1712 int last_initialized_frame_height_ GUARDED_BY(&crit_);
1713 };
1714
skvlad11a9cbf2016-10-07 11:53:05 -07001715 CreateSenderCall(Call::Config(&event_log_));
perkjfa10b552016-10-02 23:45:26 -07001716 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001717 CreateSendConfig(1, 0, 0, &transport);
perkjfa10b552016-10-02 23:45:26 -07001718 EncoderObserver encoder;
1719 video_send_config_.encoder_settings.encoder = &encoder;
1720 CreateVideoStreams();
1721 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1722 kDefaultHeight);
1723 frame_generator_capturer_->Start();
1724
1725 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
1726 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1727 kDefaultHeight * 2);
1728 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
1729 DestroyStreams();
1730}
1731
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001732TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1733 class StartBitrateObserver : public test::FakeEncoder {
1734 public:
1735 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001736 : FakeEncoder(Clock::GetRealTimeClock()),
1737 start_bitrate_changed_(false, false),
1738 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001739 int32_t InitEncode(const VideoCodec* config,
1740 int32_t number_of_cores,
1741 size_t max_payload_size) override {
1742 rtc::CritScope lock(&crit_);
1743 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001744 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001745 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1746 }
1747
1748 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1749 rtc::CritScope lock(&crit_);
1750 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001751 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001752 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1753 }
1754
1755 int GetStartBitrateKbps() const {
1756 rtc::CritScope lock(&crit_);
1757 return start_bitrate_kbps_;
1758 }
1759
pbos14fe7082016-04-20 06:35:56 -07001760 bool WaitForStartBitrate() {
1761 return start_bitrate_changed_.Wait(
1762 VideoSendStreamTest::kDefaultTimeoutMs);
1763 }
1764
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001765 private:
pbos5ad935c2016-01-25 03:52:44 -08001766 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001767 rtc::Event start_bitrate_changed_;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001768 int start_bitrate_kbps_ GUARDED_BY(crit_);
1769 };
1770
skvlad11a9cbf2016-10-07 11:53:05 -07001771 CreateSenderCall(Call::Config(&event_log_));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001772
solenberg4fbae2b2015-08-28 04:07:10 -07001773 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001774 CreateSendConfig(1, 0, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001775
1776 Call::Config::BitrateConfig bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07001777 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001778 sender_call_->SetBitrateConfig(bitrate_config);
1779
1780 StartBitrateObserver encoder;
stefanff483612015-12-21 03:14:00 -08001781 video_send_config_.encoder_settings.encoder = &encoder;
perkjfa10b552016-10-02 23:45:26 -07001782 // Since this test does not use a capturer, set |internal_source| = true.
1783 // Encoder configuration is otherwise updated on the next video frame.
1784 video_send_config_.encoder_settings.internal_source = true;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001785
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001786 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001787
pbos14fe7082016-04-20 06:35:56 -07001788 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07001789 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001790 encoder.GetStartBitrateKbps());
1791
perkjfa10b552016-10-02 23:45:26 -07001792 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07001793 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001794
1795 // New bitrate should be reconfigured above the previous max. As there's no
1796 // network connection this shouldn't be flaky, as no bitrate should've been
1797 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07001798 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001799 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
1800 encoder.GetStartBitrateKbps());
1801
1802 DestroyStreams();
1803}
1804
perkj57c21f92016-06-17 07:27:16 -07001805// This test that if the encoder use an internal source, VideoEncoder::SetRates
1806// will be called with zero bitrate during initialization and that
1807// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
1808// with zero bitrate.
1809TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
1810 class StartStopBitrateObserver : public test::FakeEncoder {
1811 public:
1812 StartStopBitrateObserver()
1813 : FakeEncoder(Clock::GetRealTimeClock()),
1814 encoder_init_(false, false),
Erik Språng08127a92016-11-16 16:41:30 +01001815 bitrate_changed_(false, false) {}
perkj57c21f92016-06-17 07:27:16 -07001816 int32_t InitEncode(const VideoCodec* config,
1817 int32_t number_of_cores,
1818 size_t max_payload_size) override {
1819 rtc::CritScope lock(&crit_);
perkj57c21f92016-06-17 07:27:16 -07001820 encoder_init_.Set();
1821 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1822 }
1823
Erik Språng08127a92016-11-16 16:41:30 +01001824 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
1825 uint32_t framerate) override {
perkj57c21f92016-06-17 07:27:16 -07001826 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01001827 bitrate_kbps_ = rtc::Optional<int>(bitrate.get_sum_kbps());
perkj57c21f92016-06-17 07:27:16 -07001828 bitrate_changed_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01001829 return FakeEncoder::SetRateAllocation(bitrate, framerate);
perkj57c21f92016-06-17 07:27:16 -07001830 }
1831
1832 bool WaitForEncoderInit() {
1833 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1834 }
Erik Språng08127a92016-11-16 16:41:30 +01001835
1836 bool WaitBitrateChanged(bool non_zero) {
1837 do {
1838 rtc::Optional<int> bitrate_kbps;
1839 {
1840 rtc::CritScope lock(&crit_);
1841 bitrate_kbps = bitrate_kbps_;
1842 }
1843 if (!bitrate_kbps)
1844 continue;
1845
1846 if ((non_zero && *bitrate_kbps > 0) ||
1847 (!non_zero && *bitrate_kbps == 0)) {
1848 return true;
1849 }
1850 } while (bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
1851 return false;
perkj57c21f92016-06-17 07:27:16 -07001852 }
1853
1854 private:
1855 rtc::CriticalSection crit_;
1856 rtc::Event encoder_init_;
1857 rtc::Event bitrate_changed_;
Erik Språng08127a92016-11-16 16:41:30 +01001858 rtc::Optional<int> bitrate_kbps_ GUARDED_BY(crit_);
perkj57c21f92016-06-17 07:27:16 -07001859 };
1860
skvlad11a9cbf2016-10-07 11:53:05 -07001861 CreateSenderCall(Call::Config(&event_log_));
perkj57c21f92016-06-17 07:27:16 -07001862
1863 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001864 CreateSendConfig(1, 0, 0, &transport);
perkj57c21f92016-06-17 07:27:16 -07001865
Sergey Ulanove2b15012016-11-22 16:08:30 -08001866 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
1867
perkj57c21f92016-06-17 07:27:16 -07001868 StartStopBitrateObserver encoder;
1869 video_send_config_.encoder_settings.encoder = &encoder;
1870 video_send_config_.encoder_settings.internal_source = true;
1871
1872 CreateVideoStreams();
1873
1874 EXPECT_TRUE(encoder.WaitForEncoderInit());
Erik Språng08127a92016-11-16 16:41:30 +01001875
perkj57c21f92016-06-17 07:27:16 -07001876 video_send_stream_->Start();
Erik Språng08127a92016-11-16 16:41:30 +01001877 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
1878
perkj57c21f92016-06-17 07:27:16 -07001879 video_send_stream_->Stop();
Erik Språng08127a92016-11-16 16:41:30 +01001880 EXPECT_TRUE(encoder.WaitBitrateChanged(false));
1881
perkj57c21f92016-06-17 07:27:16 -07001882 video_send_stream_->Start();
Erik Språng08127a92016-11-16 16:41:30 +01001883 EXPECT_TRUE(encoder.WaitBitrateChanged(true));
perkj57c21f92016-06-17 07:27:16 -07001884
1885 DestroyStreams();
1886}
1887
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001888TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07001889 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001890 public:
Peter Boström5811a392015-12-10 13:02:50 +01001891 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001892
nissed30a1112016-04-18 05:15:22 -07001893 void OnFrame(const VideoFrame& video_frame) override {
1894 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01001895 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001896 }
1897
1898 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01001899 const int kWaitFrameTimeoutMs = 3000;
1900 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001901 << "Timeout while waiting for output frames.";
1902 }
1903
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001904 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001905 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001906 }
1907
1908 private:
1909 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001910 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001911
1912 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01001913 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001914 };
1915
1916 // Initialize send stream.
skvlad11a9cbf2016-10-07 11:53:05 -07001917 CreateSenderCall(Call::Config(&event_log_));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001918
solenberg4fbae2b2015-08-28 04:07:10 -07001919 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08001920 CreateSendConfig(1, 0, 0, &transport);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001921 FrameObserver observer;
stefanff483612015-12-21 03:14:00 -08001922 video_send_config_.pre_encode_callback = &observer;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001923 CreateVideoStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001924
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001925 // Prepare five input frames. Send ordinary VideoFrame and texture frames
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001926 // alternatively.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001927 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07001928 int width = 168;
1929 int height = 132;
1930
Peter Boströmeb66e802015-06-05 11:08:03 +02001931 test::FakeNativeHandle* handle1 = new test::FakeNativeHandle();
1932 test::FakeNativeHandle* handle2 = new test::FakeNativeHandle();
1933 test::FakeNativeHandle* handle3 = new test::FakeNativeHandle();
Peter Boström13f61df2016-01-04 22:36:38 +01001934 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001935 handle1, width, height, 1, 1, kVideoRotation_0));
Peter Boström13f61df2016-01-04 22:36:38 +01001936 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001937 handle2, width, height, 2, 2, kVideoRotation_0));
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001938 input_frames.push_back(CreateVideoFrame(width, height, 3));
1939 input_frames.push_back(CreateVideoFrame(width, height, 4));
Peter Boström13f61df2016-01-04 22:36:38 +01001940 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001941 handle3, width, height, 5, 5, kVideoRotation_0));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001942
stefanff483612015-12-21 03:14:00 -08001943 video_send_stream_->Start();
perkja49cbd32016-09-16 07:53:41 -07001944 test::FrameForwarder forwarder;
perkj803d97f2016-11-01 11:45:46 -07001945 video_send_stream_->SetSource(
lliuuf9ed2352017-03-30 10:44:38 -07001946 &forwarder, VideoSendStream::DegradationPreference::kBalanced);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001947 for (size_t i = 0; i < input_frames.size(); i++) {
perkja49cbd32016-09-16 07:53:41 -07001948 forwarder.IncomingCapturedFrame(input_frames[i]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001949 // Wait until the output frame is received before sending the next input
1950 // frame. Or the previous input frame may be replaced without delivering.
1951 observer.WaitOutputFrame();
1952 }
stefanff483612015-12-21 03:14:00 -08001953 video_send_stream_->Stop();
perkj803d97f2016-11-01 11:45:46 -07001954 video_send_stream_->SetSource(
lliuuf9ed2352017-03-30 10:44:38 -07001955 nullptr, VideoSendStream::DegradationPreference::kBalanced);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001956
1957 // Test if the input and output frames are the same. render_time_ms and
1958 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001959 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001960
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001961 DestroyStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001962}
1963
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001964void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
1965 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001966 EXPECT_EQ(frames1.size(), frames2.size());
1967 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07001968 // Compare frame buffers, since we don't care about differing timestamps.
1969 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
1970 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001971}
1972
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001973VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001974 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08001975 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001976 memset(buffer.get(), data, kSizeY);
nissef0a7c5a2016-10-31 05:48:07 -07001977 VideoFrame frame(
1978 I420Buffer::Create(width, height, width, width / 2, width / 2),
1979 kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001980 frame.set_timestamp(data);
nisse1c0dea82017-01-30 02:43:18 -08001981 // Use data as a ms timestamp.
1982 frame.set_timestamp_us(data * rtc::kNumMicrosecsPerMillisec);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001983 return frame;
1984}
1985
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001986TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
1987 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
1988 public:
1989 EncoderStateObserver()
1990 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001991 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001992 initialized_(false),
1993 callback_registered_(false),
1994 num_releases_(0),
1995 released_(false) {}
1996
1997 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02001998 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001999 return released_;
2000 }
2001
2002 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002003 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002004 return initialized_ && callback_registered_;
2005 }
2006
2007 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02002008 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002009 return num_releases_;
2010 }
2011
2012 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002013 int32_t InitEncode(const VideoCodec* codecSettings,
2014 int32_t numberOfCores,
2015 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002016 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002017 EXPECT_FALSE(initialized_);
2018 initialized_ = true;
2019 released_ = false;
2020 return 0;
2021 }
2022
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002023 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002024 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002025 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002026 EXPECT_TRUE(IsReadyForEncode());
2027
Peter Boström5811a392015-12-10 13:02:50 +01002028 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002029 return 0;
2030 }
2031
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002032 int32_t RegisterEncodeCompleteCallback(
2033 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002034 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002035 EXPECT_TRUE(initialized_);
2036 callback_registered_ = true;
2037 return 0;
2038 }
2039
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002040 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02002041 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002042 EXPECT_TRUE(IsReadyForEncode());
2043 EXPECT_FALSE(released_);
2044 initialized_ = false;
2045 callback_registered_ = false;
2046 released_ = true;
2047 ++num_releases_;
2048 return 0;
2049 }
2050
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002051 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002052 EXPECT_TRUE(IsReadyForEncode());
2053 return 0;
2054 }
2055
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002056 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002057 EXPECT_TRUE(IsReadyForEncode());
2058 return 0;
2059 }
2060
stefanff483612015-12-21 03:14:00 -08002061 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002062 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002063 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002064 stream_ = send_stream;
2065 }
2066
stefanff483612015-12-21 03:14:00 -08002067 void ModifyVideoConfigs(
2068 VideoSendStream::Config* send_config,
2069 std::vector<VideoReceiveStream::Config>* receive_configs,
2070 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002071 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07002072 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002073 }
2074
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002075 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002076 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
Per21d45d22016-10-30 21:37:57 +01002077 EXPECT_EQ(0u, num_releases());
perkj26091b12016-09-01 01:17:40 -07002078 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
Per21d45d22016-10-30 21:37:57 +01002079 EXPECT_EQ(0u, num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002080 stream_->Stop();
2081 // Encoder should not be released before destroying the VideoSendStream.
2082 EXPECT_FALSE(IsReleased());
2083 EXPECT_TRUE(IsReadyForEncode());
2084 stream_->Start();
2085 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01002086 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002087 }
2088
Peter Boströmf2f82832015-05-01 13:00:41 +02002089 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002090 VideoSendStream* stream_;
2091 bool initialized_ GUARDED_BY(crit_);
2092 bool callback_registered_ GUARDED_BY(crit_);
2093 size_t num_releases_ GUARDED_BY(crit_);
2094 bool released_ GUARDED_BY(crit_);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002095 VideoEncoderConfig encoder_config_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002096 } test_encoder;
2097
stefane74eef12016-01-08 06:47:13 -08002098 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002099
2100 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01002101 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00002102}
2103
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002104TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
2105 class VideoCodecConfigObserver : public test::SendTest,
2106 public test::FakeEncoder {
2107 public:
2108 VideoCodecConfigObserver()
2109 : SendTest(kDefaultTimeoutMs),
2110 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002111 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002112 num_initializations_(0),
2113 stream_(nullptr) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002114
2115 private:
stefanff483612015-12-21 03:14:00 -08002116 void ModifyVideoConfigs(
2117 VideoSendStream::Config* send_config,
2118 std::vector<VideoReceiveStream::Config>* receive_configs,
2119 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002120 send_config->encoder_settings.encoder = this;
sprangf24a0642017-02-28 13:23:26 -08002121 encoder_config->max_bitrate_bps = kFirstMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002122 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002123 }
2124
stefanff483612015-12-21 03:14:00 -08002125 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002126 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002127 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002128 stream_ = send_stream;
2129 }
2130
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002131 int32_t InitEncode(const VideoCodec* config,
2132 int32_t number_of_cores,
2133 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01002134 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002135 // Verify default values.
sprangf24a0642017-02-28 13:23:26 -08002136 EXPECT_EQ(kFirstMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002137 } else {
2138 // Verify that changed values are propagated.
sprangf24a0642017-02-28 13:23:26 -08002139 EXPECT_EQ(kSecondMaxBitrateBps / 1000, config->maxBitrate);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002140 }
2141 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002142 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002143 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2144 }
2145
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002146 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002147 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002148 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002149
sprangf24a0642017-02-28 13:23:26 -08002150 encoder_config_.max_bitrate_bps = kSecondMaxBitrateBps;
perkj26091b12016-09-01 01:17:40 -07002151 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002152 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002153 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002154 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2155 "new encoder settings.";
2156 }
2157
sprangf24a0642017-02-28 13:23:26 -08002158 const uint32_t kFirstMaxBitrateBps = 1000000;
2159 const uint32_t kSecondMaxBitrateBps = 2000000;
2160
pbos14fe7082016-04-20 06:35:56 -07002161 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002162 size_t num_initializations_;
2163 VideoSendStream* stream_;
2164 VideoEncoderConfig encoder_config_;
2165 } test;
2166
stefane74eef12016-01-08 06:47:13 -08002167 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002168}
2169
Peter Boström53eda3d2015-03-27 15:53:18 +01002170static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
2171template <typename T>
2172class VideoCodecConfigObserver : public test::SendTest,
2173 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01002174 public:
2175 VideoCodecConfigObserver(VideoCodecType video_codec_type,
2176 const char* codec_name)
2177 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
2178 FakeEncoder(Clock::GetRealTimeClock()),
2179 video_codec_type_(video_codec_type),
2180 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07002181 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02002182 num_initializations_(0),
2183 stream_(nullptr) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002184 memset(&encoder_settings_, 0, sizeof(encoder_settings_));
2185 }
2186
2187 private:
perkjfa10b552016-10-02 23:45:26 -07002188 class VideoStreamFactory
2189 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2190 public:
2191 VideoStreamFactory() {}
2192
2193 private:
2194 std::vector<VideoStream> CreateEncoderStreams(
2195 int width,
2196 int height,
2197 const VideoEncoderConfig& encoder_config) override {
2198 std::vector<VideoStream> streams =
2199 test::CreateVideoStreams(width, height, encoder_config);
2200 for (size_t i = 0; i < streams.size(); ++i) {
2201 streams[i].temporal_layer_thresholds_bps.resize(
2202 kVideoCodecConfigObserverNumberOfTemporalLayers - 1);
2203 }
2204 return streams;
2205 }
2206 };
2207
stefanff483612015-12-21 03:14:00 -08002208 void ModifyVideoConfigs(
2209 VideoSendStream::Config* send_config,
2210 std::vector<VideoReceiveStream::Config>* receive_configs,
2211 VideoEncoderConfig* encoder_config) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002212 send_config->encoder_settings.encoder = this;
2213 send_config->encoder_settings.payload_name = codec_name_;
2214
kthelgason29a44e32016-09-27 03:52:02 -07002215 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07002216 encoder_config->video_stream_factory =
2217 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07002218 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01002219 }
2220
stefanff483612015-12-21 03:14:00 -08002221 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01002222 VideoSendStream* send_stream,
2223 const std::vector<VideoReceiveStream*>& receive_streams) override {
2224 stream_ = send_stream;
2225 }
2226
2227 int32_t InitEncode(const VideoCodec* config,
2228 int32_t number_of_cores,
2229 size_t max_payload_size) override {
2230 EXPECT_EQ(video_codec_type_, config->codecType);
2231 VerifyCodecSpecifics(*config);
2232 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002233 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01002234 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
2235 }
2236
2237 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07002238 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2239 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01002240
2241 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002242 EXPECT_TRUE(
2243 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002244 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01002245
2246 encoder_settings_.frameDroppingOn = true;
kthelgason29a44e32016-09-27 03:52:02 -07002247 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07002248 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07002249 ASSERT_TRUE(
2250 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002251 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002252 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2253 "new encoder settings.";
2254 }
2255
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002256 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002257 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002258 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002259 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2260 return 0;
2261 }
2262
2263 T encoder_settings_;
2264 const VideoCodecType video_codec_type_;
2265 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002266 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002267 size_t num_initializations_;
2268 VideoSendStream* stream_;
2269 VideoEncoderConfig encoder_config_;
2270};
2271
2272template <>
2273void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2274 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002275 EXPECT_EQ(
2276 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002277}
kthelgason29a44e32016-09-27 03:52:02 -07002278
2279template <>
2280rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2281VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2282 return new rtc::RefCountedObject<
2283 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2284}
2285
Peter Boström53eda3d2015-03-27 15:53:18 +01002286template <>
2287void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2288 const VideoCodec& config) const {
2289 // Check that the number of temporal layers has propagated properly to
2290 // VideoCodec.
2291 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002292 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002293
2294 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2295 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2296 config.simulcastStream[i].numberOfTemporalLayers);
2297 }
2298
2299 // Set expected temporal layers as they should have been set when
Erik Språng08127a92016-11-16 16:41:30 +01002300 // reconfiguring the encoder and not match the set config. Also copy the
2301 // TemporalLayersFactory pointer that has been injected by ViEEncoder.
Peter Boström53eda3d2015-03-27 15:53:18 +01002302 VideoCodecVP8 encoder_settings = encoder_settings_;
2303 encoder_settings.numberOfTemporalLayers =
2304 kVideoCodecConfigObserverNumberOfTemporalLayers;
Erik Språng08127a92016-11-16 16:41:30 +01002305 encoder_settings.tl_factory = config.VP8().tl_factory;
hta257dc392016-10-25 09:05:06 -07002306 EXPECT_EQ(
2307 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002308}
kthelgason29a44e32016-09-27 03:52:02 -07002309
2310template <>
2311rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2312VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2313 return new rtc::RefCountedObject<
2314 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2315}
2316
Peter Boström53eda3d2015-03-27 15:53:18 +01002317template <>
2318void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2319 const VideoCodec& config) const {
2320 // Check that the number of temporal layers has propagated properly to
2321 // VideoCodec.
2322 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002323 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002324
2325 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2326 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2327 config.simulcastStream[i].numberOfTemporalLayers);
2328 }
2329
2330 // Set expected temporal layers as they should have been set when
2331 // reconfiguring the encoder and not match the set config.
2332 VideoCodecVP9 encoder_settings = encoder_settings_;
2333 encoder_settings.numberOfTemporalLayers =
2334 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002335 EXPECT_EQ(
2336 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002337}
2338
kthelgason29a44e32016-09-27 03:52:02 -07002339template <>
2340rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2341VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2342 return new rtc::RefCountedObject<
2343 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2344}
2345
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002346TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002347 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002348 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002349}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002350
Peter Boström53eda3d2015-03-27 15:53:18 +01002351TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2352 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002353 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002354}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002355
Peter Boström53eda3d2015-03-27 15:53:18 +01002356TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2357 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002358 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002359}
2360
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002361TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002362 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002363 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002364 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2365 rtp_packets_sent_(0),
2366 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002367
2368 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002369 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002370 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002371 RTPHeader header;
2372 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002373 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002374 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2375 return SEND_PACKET;
2376 }
2377
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002378 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002379 rtc::CritScope lock(&crit_);
danilchap3dc929e2016-11-02 08:21:59 -07002380 test::RtcpPacketParser parser;
2381 EXPECT_TRUE(parser.Parse(packet, length));
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002382
danilchap3dc929e2016-11-02 08:21:59 -07002383 if (parser.sender_report()->num_packets() > 0) {
2384 // Only compare sent media bytes if SenderPacketCount matches the
2385 // number of sent rtp packets (a new rtp packet could be sent before
2386 // the rtcp packet).
2387 if (parser.sender_report()->sender_octet_count() > 0 &&
2388 parser.sender_report()->sender_packet_count() ==
2389 rtp_packets_sent_) {
2390 EXPECT_EQ(media_bytes_sent_,
2391 parser.sender_report()->sender_octet_count());
2392 observation_complete_.Set();
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002393 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002394 }
2395
2396 return SEND_PACKET;
2397 }
2398
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002399 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002400 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002401 }
2402
stefan4b569042015-11-11 06:39:57 -08002403 rtc::CriticalSection crit_;
2404 size_t rtp_packets_sent_ GUARDED_BY(&crit_);
2405 size_t media_bytes_sent_ GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002406 } test;
2407
stefane74eef12016-01-08 06:47:13 -08002408 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002409}
2410
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002411TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
2412 static const int kScreencastTargetBitrateKbps = 200;
perkjfa10b552016-10-02 23:45:26 -07002413
2414 class VideoStreamFactory
2415 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2416 public:
2417 VideoStreamFactory() {}
2418
2419 private:
2420 std::vector<VideoStream> CreateEncoderStreams(
2421 int width,
2422 int height,
2423 const VideoEncoderConfig& encoder_config) override {
2424 std::vector<VideoStream> streams =
2425 test::CreateVideoStreams(width, height, encoder_config);
2426 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
2427 streams[0].temporal_layer_thresholds_bps.push_back(
2428 kScreencastTargetBitrateKbps * 1000);
2429 return streams;
2430 }
2431 };
2432
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002433 class ScreencastTargetBitrateTest : public test::SendTest,
2434 public test::FakeEncoder {
2435 public:
2436 ScreencastTargetBitrateTest()
2437 : SendTest(kDefaultTimeoutMs),
2438 test::FakeEncoder(Clock::GetRealTimeClock()) {}
2439
2440 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002441 int32_t InitEncode(const VideoCodec* config,
2442 int32_t number_of_cores,
2443 size_t max_payload_size) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002444 EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps),
2445 config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002446 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002447 return test::FakeEncoder::InitEncode(
2448 config, number_of_cores, max_payload_size);
2449 }
stefanff483612015-12-21 03:14:00 -08002450 void ModifyVideoConfigs(
2451 VideoSendStream::Config* send_config,
2452 std::vector<VideoReceiveStream::Config>* receive_configs,
2453 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002454 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002455 EXPECT_EQ(1u, encoder_config->number_of_streams);
2456 encoder_config->video_stream_factory =
2457 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002458 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002459 }
2460
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002461 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002462 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002463 << "Timed out while waiting for the encoder to be initialized.";
2464 }
2465 } test;
2466
stefane74eef12016-01-08 06:47:13 -08002467 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002468}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002469
philipelc6957c72016-04-28 15:52:49 +02002470TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002471 // These are chosen to be "kind of odd" to not be accidentally checked against
2472 // default values.
2473 static const int kMinBitrateKbps = 137;
2474 static const int kStartBitrateKbps = 345;
2475 static const int kLowerMaxBitrateKbps = 312;
2476 static const int kMaxBitrateKbps = 413;
2477 static const int kIncreasedStartBitrateKbps = 451;
2478 static const int kIncreasedMaxBitrateKbps = 597;
2479 class EncoderBitrateThresholdObserver : public test::SendTest,
2480 public test::FakeEncoder {
2481 public:
2482 EncoderBitrateThresholdObserver()
2483 : SendTest(kDefaultTimeoutMs),
2484 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002485 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002486 bitrate_changed_event_(false, false),
2487 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002488 num_initializations_(0),
2489 call_(nullptr),
2490 send_stream_(nullptr) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002491
2492 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002493 int32_t InitEncode(const VideoCodec* codecSettings,
2494 int32_t numberOfCores,
2495 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002496 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2497 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002498 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002499 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2500 codecSettings->minBitrate);
2501 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2502 codecSettings->startBitrate);
2503 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2504 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002505 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002506 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002507 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2508 codecSettings->maxBitrate);
2509 // The start bitrate should be kept (-1) and capped to the max bitrate.
2510 // Since this is not an end-to-end call no receiver should have been
2511 // returning a REMB that could lower this estimate.
2512 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002513 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002514 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2515 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002516 // The start bitrate will be whatever the rate BitRateController
2517 // has currently configured but in the span of the set max and min
2518 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002519 }
2520 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002521 init_encode_event_.Set();
2522
pbos@webrtc.org00873182014-11-25 14:03:34 +00002523 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2524 maxPayloadSize);
2525 }
2526
Erik Språng08127a92016-11-16 16:41:30 +01002527 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
2528 uint32_t frameRate) override {
perkj26091b12016-09-01 01:17:40 -07002529 {
2530 rtc::CritScope lock(&crit_);
Erik Språng08127a92016-11-16 16:41:30 +01002531 if (target_bitrate_ == bitrate.get_sum_kbps()) {
2532 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkjfa10b552016-10-02 23:45:26 -07002533 }
Erik Språng08127a92016-11-16 16:41:30 +01002534 target_bitrate_ = bitrate.get_sum_kbps();
perkj26091b12016-09-01 01:17:40 -07002535 }
2536 bitrate_changed_event_.Set();
Erik Språng08127a92016-11-16 16:41:30 +01002537 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
perkj26091b12016-09-01 01:17:40 -07002538 }
2539
2540 void WaitForSetRates(uint32_t expected_bitrate) {
2541 EXPECT_TRUE(
2542 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2543 << "Timed out while waiting encoder rate to be set.";
2544 rtc::CritScope lock(&crit_);
2545 EXPECT_EQ(expected_bitrate, target_bitrate_);
2546 }
2547
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002548 Call::Config GetSenderCallConfig() override {
skvlad11a9cbf2016-10-07 11:53:05 -07002549 Call::Config config(&event_log_);
Stefan Holmere5904162015-03-26 11:11:06 +01002550 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2551 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2552 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002553 return config;
2554 }
2555
perkjfa10b552016-10-02 23:45:26 -07002556 class VideoStreamFactory
2557 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2558 public:
2559 explicit VideoStreamFactory(int min_bitrate_bps)
2560 : min_bitrate_bps_(min_bitrate_bps) {}
2561
2562 private:
2563 std::vector<VideoStream> CreateEncoderStreams(
2564 int width,
2565 int height,
2566 const VideoEncoderConfig& encoder_config) override {
2567 std::vector<VideoStream> streams =
2568 test::CreateVideoStreams(width, height, encoder_config);
2569 streams[0].min_bitrate_bps = min_bitrate_bps_;
2570 return streams;
2571 }
2572
2573 const int min_bitrate_bps_;
2574 };
2575
stefanff483612015-12-21 03:14:00 -08002576 void ModifyVideoConfigs(
2577 VideoSendStream::Config* send_config,
2578 std::vector<VideoReceiveStream::Config>* receive_configs,
2579 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002580 send_config->encoder_settings.encoder = this;
2581 // Set bitrates lower/higher than min/max to make sure they are properly
2582 // capped.
perkjfa10b552016-10-02 23:45:26 -07002583 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2584 // Create a new StreamFactory to be able to set
2585 // |VideoStream.min_bitrate_bps|.
2586 encoder_config->video_stream_factory =
2587 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002588 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002589 }
2590
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002591 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002592 call_ = sender_call;
2593 }
2594
stefanff483612015-12-21 03:14:00 -08002595 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002596 VideoSendStream* send_stream,
2597 const std::vector<VideoReceiveStream*>& receive_streams) override {
2598 send_stream_ = send_stream;
2599 }
2600
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002601 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002602 ASSERT_TRUE(
2603 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002604 << "Timed out while waiting for encoder to be configured.";
2605 WaitForSetRates(kStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002606 Call::Config::BitrateConfig bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002607 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2608 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2609 call_->SetBitrateConfig(bitrate_config);
perkj26091b12016-09-01 01:17:40 -07002610 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2611 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002612 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002613 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002614 ASSERT_TRUE(
2615 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002616 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002617 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002618 WaitForSetRates(kLowerMaxBitrateKbps);
2619
2620 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2621 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2622 ASSERT_TRUE(
2623 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002624 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002625 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002626 // Expected target bitrate is the start bitrate set in the call to
2627 // call_->SetBitrateConfig.
2628 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002629 }
2630
pbos14fe7082016-04-20 06:35:56 -07002631 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002632 rtc::Event bitrate_changed_event_;
2633 rtc::CriticalSection crit_;
2634 uint32_t target_bitrate_ GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002635
pbos@webrtc.org00873182014-11-25 14:03:34 +00002636 int num_initializations_;
2637 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002638 webrtc::VideoSendStream* send_stream_;
2639 webrtc::VideoEncoderConfig encoder_config_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002640 } test;
2641
stefane74eef12016-01-08 06:47:13 -08002642 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002643}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002644
2645TEST_F(VideoSendStreamTest, ReportsSentResolution) {
2646 static const size_t kNumStreams = 3;
2647 // Unusual resolutions to make sure that they are the ones being reported.
2648 static const struct {
2649 int width;
2650 int height;
2651 } kEncodedResolution[kNumStreams] = {
2652 {241, 181}, {300, 121}, {121, 221}};
2653 class ScreencastTargetBitrateTest : public test::SendTest,
2654 public test::FakeEncoder {
2655 public:
2656 ScreencastTargetBitrateTest()
2657 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002658 test::FakeEncoder(Clock::GetRealTimeClock()),
2659 send_stream_(nullptr) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002660
2661 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002662 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002663 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002664 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002665 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002666 specifics.codecType = kVideoCodecGeneric;
2667
2668 uint8_t buffer[16] = {0};
2669 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
2670 encoded._timeStamp = input_image.timestamp();
2671 encoded.capture_time_ms_ = input_image.render_time_ms();
2672
2673 for (size_t i = 0; i < kNumStreams; ++i) {
2674 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
2675 encoded._frameType = (*frame_types)[i];
2676 encoded._encodedWidth = kEncodedResolution[i].width;
2677 encoded._encodedHeight = kEncodedResolution[i].height;
brandtre78d2662017-01-16 05:57:16 -08002678 EncodedImageCallback* callback;
2679 {
2680 rtc::CritScope cs(&crit_sect_);
2681 callback = callback_;
2682 }
2683 RTC_DCHECK(callback);
2684 if (callback->OnEncodedImage(encoded, &specifics, nullptr).error !=
sergeyu2cb155a2016-11-04 11:39:29 -07002685 EncodedImageCallback::Result::OK) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002686 return -1;
sergeyu2cb155a2016-11-04 11:39:29 -07002687 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002688 }
2689
Peter Boström5811a392015-12-10 13:02:50 +01002690 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002691 return 0;
2692 }
stefanff483612015-12-21 03:14:00 -08002693 void ModifyVideoConfigs(
2694 VideoSendStream::Config* send_config,
2695 std::vector<VideoReceiveStream::Config>* receive_configs,
2696 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002697 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002698 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002699 }
2700
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002701 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002702
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002703 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002704 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002705 << "Timed out while waiting for the encoder to send one frame.";
2706 VideoSendStream::Stats stats = send_stream_->GetStats();
2707
2708 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002709 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002710 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002711 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002712 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002713 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002714 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002715 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
2716 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002717 }
2718 }
2719
stefanff483612015-12-21 03:14:00 -08002720 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002721 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002722 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002723 send_stream_ = send_stream;
2724 }
2725
2726 VideoSendStream* send_stream_;
2727 } test;
2728
stefane74eef12016-01-08 06:47:13 -08002729 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002730}
philipel0f9af012015-09-01 07:01:51 -07002731
Peter Boström12996152016-05-14 02:03:18 +02002732#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01002733class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07002734 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01002735 Vp9HeaderObserver()
2736 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
philipel7fabd462015-09-03 04:42:32 -07002737 vp9_encoder_(VP9Encoder::Create()),
Åsa Perssonff24c042015-12-04 10:58:08 +01002738 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
2739 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07002740 frames_sent_(0),
2741 expected_width_(0),
2742 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07002743
stefanff483612015-12-21 03:14:00 -08002744 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07002745 VideoSendStream::Config* send_config,
2746 std::vector<VideoReceiveStream::Config>* receive_configs,
2747 VideoEncoderConfig* encoder_config) {}
2748
Åsa Perssonff24c042015-12-04 10:58:08 +01002749 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07002750
2751 private:
2752 const int kVp9PayloadType = 105;
2753
perkjfa10b552016-10-02 23:45:26 -07002754 class VideoStreamFactory
2755 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2756 public:
2757 explicit VideoStreamFactory(size_t number_of_temporal_layers)
2758 : number_of_temporal_layers_(number_of_temporal_layers) {}
2759
2760 private:
2761 std::vector<VideoStream> CreateEncoderStreams(
2762 int width,
2763 int height,
2764 const VideoEncoderConfig& encoder_config) override {
2765 std::vector<VideoStream> streams =
2766 test::CreateVideoStreams(width, height, encoder_config);
2767 streams[0].temporal_layer_thresholds_bps.resize(
2768 number_of_temporal_layers_ - 1);
2769 return streams;
2770 }
2771
2772 const size_t number_of_temporal_layers_;
2773 };
2774
stefanff483612015-12-21 03:14:00 -08002775 void ModifyVideoConfigs(
2776 VideoSendStream::Config* send_config,
2777 std::vector<VideoReceiveStream::Config>* receive_configs,
2778 VideoEncoderConfig* encoder_config) override {
philipel7fabd462015-09-03 04:42:32 -07002779 send_config->encoder_settings.encoder = vp9_encoder_.get();
philipel0f9af012015-09-01 07:01:51 -07002780 send_config->encoder_settings.payload_name = "VP9";
2781 send_config->encoder_settings.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08002782 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07002783 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
2784 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07002785 EXPECT_EQ(1u, encoder_config->number_of_streams);
2786 encoder_config->video_stream_factory =
2787 new rtc::RefCountedObject<VideoStreamFactory>(
2788 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07002789 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07002790 }
2791
perkjfa10b552016-10-02 23:45:26 -07002792 void ModifyVideoCaptureStartResolution(int* width,
2793 int* height,
2794 int* frame_rate) override {
2795 expected_width_ = *width;
2796 expected_height_ = *height;
2797 }
2798
philipel0f9af012015-09-01 07:01:51 -07002799 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002800 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
2801 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002802 }
2803
2804 Action OnSendRtp(const uint8_t* packet, size_t length) override {
2805 RTPHeader header;
2806 EXPECT_TRUE(parser_->Parse(packet, length, &header));
2807
Åsa Perssonff24c042015-12-04 10:58:08 +01002808 EXPECT_EQ(kVp9PayloadType, header.payloadType);
2809 const uint8_t* payload = packet + header.headerLength;
2810 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07002811
Åsa Perssonff24c042015-12-04 10:58:08 +01002812 bool new_packet = packets_sent_ == 0 ||
2813 IsNewerSequenceNumber(header.sequenceNumber,
2814 last_header_.sequenceNumber);
2815 if (payload_length > 0 && new_packet) {
2816 RtpDepacketizer::ParsedPayload parsed;
2817 RtpDepacketizerVp9 depacketizer;
2818 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
2819 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
2820 // Verify common fields for all configurations.
2821 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
2822 CompareConsecutiveFrames(header, parsed.type.Video);
2823 // Verify configuration specific settings.
2824 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07002825
Åsa Perssonff24c042015-12-04 10:58:08 +01002826 ++packets_sent_;
2827 if (header.markerBit) {
2828 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002829 }
Åsa Perssonff24c042015-12-04 10:58:08 +01002830 last_header_ = header;
2831 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07002832 }
philipel0f9af012015-09-01 07:01:51 -07002833 return SEND_PACKET;
2834 }
2835
philipel7fabd462015-09-03 04:42:32 -07002836 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01002837 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
2838 if (last_vp9_.picture_id > vp9.picture_id) {
2839 return vp9.picture_id == 0; // Wrap.
2840 } else {
2841 return vp9.picture_id == last_vp9_.picture_id + 1;
2842 }
2843 }
2844
2845 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01002846 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
2847 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
2848 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
2849 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
2850 vp9.spatial_idx);
2851 }
2852
2853 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
2854 uint8_t num_layers) const {
2855 switch (num_layers) {
2856 case 0:
2857 VerifyTemporalLayerStructure0(vp9);
2858 break;
2859 case 1:
2860 VerifyTemporalLayerStructure1(vp9);
2861 break;
2862 case 2:
2863 VerifyTemporalLayerStructure2(vp9);
2864 break;
2865 case 3:
2866 VerifyTemporalLayerStructure3(vp9);
2867 break;
2868 default:
2869 RTC_NOTREACHED();
2870 }
2871 }
2872
2873 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
2874 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
2875 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
2876 EXPECT_FALSE(vp9.temporal_up_switch);
2877 }
2878
2879 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
2880 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2881 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
2882 EXPECT_FALSE(vp9.temporal_up_switch);
2883 }
2884
2885 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
2886 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2887 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
2888 EXPECT_LE(vp9.temporal_idx, 1);
2889 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
2890 if (IsNewPictureId(vp9)) {
2891 uint8_t expected_tid =
2892 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
2893 EXPECT_EQ(expected_tid, vp9.temporal_idx);
2894 }
2895 }
2896
2897 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
2898 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2899 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
2900 EXPECT_LE(vp9.temporal_idx, 2);
2901 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
2902 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
2903 switch (vp9.temporal_idx) {
2904 case 0:
2905 EXPECT_EQ(2, last_vp9_.temporal_idx);
2906 EXPECT_FALSE(vp9.temporal_up_switch);
2907 break;
2908 case 1:
2909 EXPECT_EQ(2, last_vp9_.temporal_idx);
2910 EXPECT_TRUE(vp9.temporal_up_switch);
2911 break;
2912 case 2:
2913 EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
2914 break;
2915 }
2916 }
2917 }
2918
2919 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
2920 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
2921 return;
2922
2923 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
2924 if (vp9.temporal_idx == 0)
2925 ++expected_tl0_idx;
2926 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
2927 }
2928
2929 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
2930 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
2931 }
2932
2933 // Flexible mode (F=1): Non-flexible mode (F=0):
2934 //
2935 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2936 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
2937 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2938 // I: |M| PICTURE ID | I: |M| PICTURE ID |
2939 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2940 // M: | EXTENDED PID | M: | EXTENDED PID |
2941 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2942 // L: | T |U| S |D| L: | T |U| S |D|
2943 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2944 // P,F: | P_DIFF |X|N| | TL0PICIDX |
2945 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2946 // X: |EXTENDED P_DIFF| V: | SS .. |
2947 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2948 // V: | SS .. |
2949 // +-+-+-+-+-+-+-+-+
2950 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
2951 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
2952 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
2953 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
2954 EXPECT_GE(vp9.spatial_idx, 0); // S
2955 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
2956 if (vp9.ss_data_available) // V
2957 VerifySsData(vp9);
2958
2959 if (frames_sent_ == 0)
2960 EXPECT_FALSE(vp9.inter_pic_predicted); // P
2961
2962 if (!vp9.inter_pic_predicted) {
2963 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
2964 EXPECT_FALSE(vp9.temporal_up_switch);
2965 }
2966 }
2967
2968 // Scalability structure (SS).
2969 //
2970 // +-+-+-+-+-+-+-+-+
2971 // V: | N_S |Y|G|-|-|-|
2972 // +-+-+-+-+-+-+-+-+
2973 // Y: | WIDTH | N_S + 1 times
2974 // +-+-+-+-+-+-+-+-+
2975 // | HEIGHT |
2976 // +-+-+-+-+-+-+-+-+
2977 // G: | N_G |
2978 // +-+-+-+-+-+-+-+-+
2979 // N_G: | T |U| R |-|-| N_G times
2980 // +-+-+-+-+-+-+-+-+
2981 // | P_DIFF | R times
2982 // +-+-+-+-+-+-+-+-+
2983 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
2984 EXPECT_TRUE(vp9.ss_data_available); // V
2985 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
2986 vp9.num_spatial_layers);
2987 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07002988 int expected_width = expected_width_;
2989 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02002990 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01002991 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
2992 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
2993 expected_width /= 2;
2994 expected_height /= 2;
2995 }
2996 }
2997
2998 void CompareConsecutiveFrames(const RTPHeader& header,
2999 const RTPVideoHeader& video) const {
3000 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
3001
3002 bool new_frame = packets_sent_ == 0 ||
3003 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
johan0d1b2b62017-01-10 04:21:35 -08003004 EXPECT_EQ(new_frame, video.is_first_packet_in_frame);
Åsa Perssonff24c042015-12-04 10:58:08 +01003005 if (!new_frame) {
3006 EXPECT_FALSE(last_header_.markerBit);
3007 EXPECT_EQ(last_header_.timestamp, header.timestamp);
3008 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
3009 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
3010 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
3011 VerifySpatialIdxWithinFrame(vp9);
3012 return;
3013 }
3014 // New frame.
3015 EXPECT_TRUE(vp9.beginning_of_frame);
3016
3017 // Compare with last packet in previous frame.
3018 if (frames_sent_ == 0)
3019 return;
3020 EXPECT_TRUE(last_vp9_.end_of_frame);
3021 EXPECT_TRUE(last_header_.markerBit);
3022 EXPECT_TRUE(ContinuousPictureId(vp9));
3023 VerifyTl0Idx(vp9);
3024 }
3025
kwiberg27f982b2016-03-01 11:52:33 -08003026 std::unique_ptr<VP9Encoder> vp9_encoder_;
philipel0f9af012015-09-01 07:01:51 -07003027 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01003028 webrtc::VideoEncoderConfig encoder_config_;
3029 RTPHeader last_header_;
3030 RTPVideoHeaderVP9 last_vp9_;
3031 size_t packets_sent_;
3032 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07003033 int expected_width_;
3034 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07003035};
3036
Åsa Perssonff24c042015-12-04 10:58:08 +01003037TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
3038 const uint8_t kNumTemporalLayers = 1;
3039 const uint8_t kNumSpatialLayers = 1;
3040 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3041}
3042
3043TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
3044 const uint8_t kNumTemporalLayers = 2;
3045 const uint8_t kNumSpatialLayers = 1;
3046 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3047}
3048
3049TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
3050 const uint8_t kNumTemporalLayers = 3;
3051 const uint8_t kNumSpatialLayers = 1;
3052 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3053}
3054
3055TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
3056 const uint8_t kNumTemporalLayers = 1;
3057 const uint8_t kNumSpatialLayers = 2;
3058 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3059}
3060
3061TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
3062 const uint8_t kNumTemporalLayers = 2;
3063 const uint8_t kNumSpatialLayers = 2;
3064 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3065}
3066
3067TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
3068 const uint8_t kNumTemporalLayers = 3;
3069 const uint8_t kNumSpatialLayers = 2;
3070 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
3071}
3072
3073void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
3074 uint8_t num_spatial_layers) {
3075 static const size_t kNumFramesToSend = 100;
3076 // Set to < kNumFramesToSend and coprime to length of temporal layer
3077 // structures to verify temporal id reset on key frame.
3078 static const int kKeyFrameInterval = 31;
3079 class NonFlexibleMode : public Vp9HeaderObserver {
3080 public:
3081 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
3082 : num_temporal_layers_(num_temporal_layers),
3083 num_spatial_layers_(num_spatial_layers),
3084 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
stefanff483612015-12-21 03:14:00 -08003085 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07003086 VideoSendStream::Config* send_config,
3087 std::vector<VideoReceiveStream::Config>* receive_configs,
3088 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003089 vp9_settings_.flexibleMode = false;
3090 vp9_settings_.frameDroppingOn = false;
3091 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
3092 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
3093 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07003094 }
3095
Åsa Perssonff24c042015-12-04 10:58:08 +01003096 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
3097 bool ss_data_expected = !vp9.inter_pic_predicted &&
3098 vp9.beginning_of_frame && vp9.spatial_idx == 0;
3099 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
3100 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted); // D
asapersson38bb8ad2015-12-14 01:41:19 -08003101 EXPECT_EQ(!vp9.inter_pic_predicted,
3102 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01003103
3104 if (IsNewPictureId(vp9)) {
3105 EXPECT_EQ(0, vp9.spatial_idx);
3106 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
3107 }
3108
3109 VerifyFixedTemporalLayerStructure(vp9,
3110 l_field_ ? num_temporal_layers_ : 0);
3111
3112 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01003113 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07003114 }
Åsa Perssonff24c042015-12-04 10:58:08 +01003115 const uint8_t num_temporal_layers_;
3116 const uint8_t num_spatial_layers_;
3117 const bool l_field_;
3118 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08003119
stefane74eef12016-01-08 06:47:13 -08003120 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003121}
3122
asaperssond9f641e2016-01-21 01:11:35 -08003123TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
3124 static const size_t kNumFramesToSend = 50;
3125 static const int kWidth = 4;
3126 static const int kHeight = 4;
3127 class NonFlexibleModeResolution : public Vp9HeaderObserver {
3128 void ModifyVideoConfigsHook(
3129 VideoSendStream::Config* send_config,
3130 std::vector<VideoReceiveStream::Config>* receive_configs,
3131 VideoEncoderConfig* encoder_config) override {
3132 vp9_settings_.flexibleMode = false;
3133 vp9_settings_.numberOfTemporalLayers = 1;
3134 vp9_settings_.numberOfSpatialLayers = 1;
3135
perkjfa10b552016-10-02 23:45:26 -07003136 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08003137 }
3138
3139 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3140 if (frames_sent_ > kNumFramesToSend)
3141 observation_complete_.Set();
3142 }
perkjfa10b552016-10-02 23:45:26 -07003143
3144 void ModifyVideoCaptureStartResolution(int* width,
3145 int* height,
3146 int* frame_rate) override {
3147 expected_width_ = kWidth;
3148 expected_height_ = kHeight;
3149 *width = kWidth;
3150 *height = kHeight;
3151 }
asaperssond9f641e2016-01-21 01:11:35 -08003152 } test;
3153
3154 RunBaseTest(&test);
3155}
3156
kjellanderf9e2a362017-03-24 12:17:33 -07003157#if defined(WEBRTC_ANDROID)
3158// Crashes on Android; bugs.webrtc.org/7401
3159#define MAYBE_Vp9FlexModeRefCount DISABLED_Vp9FlexModeRefCount
3160#else
3161#define MAYBE_Vp9FlexModeRefCount Vp9FlexModeRefCount
3162#endif
3163TEST_F(VideoSendStreamTest, MAYBE_Vp9FlexModeRefCount) {
Åsa Perssonff24c042015-12-04 10:58:08 +01003164 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08003165 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08003166 VideoSendStream::Config* send_config,
3167 std::vector<VideoReceiveStream::Config>* receive_configs,
3168 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01003169 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08003170 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01003171 vp9_settings_.numberOfTemporalLayers = 1;
3172 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08003173 }
3174
Åsa Perssonff24c042015-12-04 10:58:08 +01003175 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
3176 EXPECT_TRUE(vp9_header.flexible_mode);
3177 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
3178 if (vp9_header.inter_pic_predicted) {
3179 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01003180 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08003181 }
3182 }
3183 } test;
3184
stefane74eef12016-01-08 06:47:13 -08003185 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08003186}
Peter Boström12996152016-05-14 02:03:18 +02003187#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08003188
perkj803d97f2016-11-01 11:45:46 -07003189void VideoSendStreamTest::TestRequestSourceRotateVideo(
3190 bool support_orientation_ext) {
3191 CreateSenderCall(Call::Config(&event_log_));
3192
3193 test::NullTransport transport;
brandtr841de6a2016-11-15 07:10:52 -08003194 CreateSendConfig(1, 0, 0, &transport);
perkj803d97f2016-11-01 11:45:46 -07003195 video_send_config_.rtp.extensions.clear();
3196 if (support_orientation_ext) {
3197 video_send_config_.rtp.extensions.push_back(
3198 RtpExtension(RtpExtension::kVideoRotationUri, 1));
3199 }
3200
3201 CreateVideoStreams();
3202 test::FrameForwarder forwarder;
3203 video_send_stream_->SetSource(
lliuuf9ed2352017-03-30 10:44:38 -07003204 &forwarder, VideoSendStream::DegradationPreference::kBalanced);
perkj803d97f2016-11-01 11:45:46 -07003205
3206 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
3207 support_orientation_ext);
3208
3209 DestroyStreams();
3210}
3211
3212TEST_F(VideoSendStreamTest,
3213 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
3214 TestRequestSourceRotateVideo(false);
3215}
3216
3217TEST_F(VideoSendStreamTest,
3218 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
3219 TestRequestSourceRotateVideo(true);
3220}
3221
michaelta3328772016-11-29 09:25:03 -08003222// This test verifies that overhead is removed from the bandwidth estimate by
3223// testing that the maximum possible target payload rate is smaller than the
3224// maximum bandwidth estimate by the overhead rate.
michaelt273f31b2017-02-08 08:21:52 -08003225TEST_F(VideoSendStreamTest, RemoveOverheadFromBandwidth) {
michaelta3328772016-11-29 09:25:03 -08003226 test::ScopedFieldTrials override_field_trials(
3227 "WebRTC-SendSideBwe-WithOverhead/Enabled/");
3228 class RemoveOverheadFromBandwidthTest : public test::EndToEndTest,
3229 public test::FakeEncoder {
3230 public:
3231 RemoveOverheadFromBandwidthTest()
3232 : EndToEndTest(test::CallTest::kDefaultTimeoutMs),
3233 FakeEncoder(Clock::GetRealTimeClock()),
3234 call_(nullptr),
michaelt192132e2017-01-26 09:05:27 -08003235 max_bitrate_bps_(0),
3236 first_packet_sent_(false),
3237 bitrate_changed_event_(false, false) {}
michaelta3328772016-11-29 09:25:03 -08003238
3239 int32_t SetRateAllocation(const BitrateAllocation& bitrate,
3240 uint32_t frameRate) override {
3241 rtc::CritScope lock(&crit_);
michaelt192132e2017-01-26 09:05:27 -08003242 // Wait for the first sent packet so that videosendstream knows
3243 // rtp_overhead.
3244 if (first_packet_sent_) {
3245 max_bitrate_bps_ = bitrate.get_sum_bps();
3246 bitrate_changed_event_.Set();
3247 }
michaelta3328772016-11-29 09:25:03 -08003248 return FakeEncoder::SetRateAllocation(bitrate, frameRate);
3249 }
3250
3251 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
3252 call_ = sender_call;
3253 }
3254
3255 void ModifyVideoConfigs(
3256 VideoSendStream::Config* send_config,
3257 std::vector<VideoReceiveStream::Config>* receive_configs,
3258 VideoEncoderConfig* encoder_config) override {
3259 send_config->rtp.max_packet_size = 1200;
3260 send_config->encoder_settings.encoder = this;
3261 EXPECT_FALSE(send_config->rtp.extensions.empty());
3262 }
3263
michaelt192132e2017-01-26 09:05:27 -08003264 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3265 rtc::CritScope lock(&crit_);
3266 first_packet_sent_ = true;
3267 return SEND_PACKET;
3268 }
3269
michaelta3328772016-11-29 09:25:03 -08003270 void PerformTest() override {
michaelta3328772016-11-29 09:25:03 -08003271 Call::Config::BitrateConfig bitrate_config;
michaelt192132e2017-01-26 09:05:27 -08003272 constexpr int kStartBitrateBps = 60000;
michaelta3328772016-11-29 09:25:03 -08003273 constexpr int kMaxBitrateBps = 60000;
michaelt192132e2017-01-26 09:05:27 -08003274 constexpr int kMinBitrateBps = 10000;
michaelta3328772016-11-29 09:25:03 -08003275 bitrate_config.start_bitrate_bps = kStartBitrateBps;
3276 bitrate_config.max_bitrate_bps = kMaxBitrateBps;
michaelt192132e2017-01-26 09:05:27 -08003277 bitrate_config.min_bitrate_bps = kMinBitrateBps;
michaelta3328772016-11-29 09:25:03 -08003278 call_->SetBitrateConfig(bitrate_config);
michaelt273f31b2017-02-08 08:21:52 -08003279 call_->OnTransportOverheadChanged(webrtc::MediaType::VIDEO, 40);
michaelta3328772016-11-29 09:25:03 -08003280
3281 // At a bitrate of 60kbps with a packet size of 1200B video and an
michaelt192132e2017-01-26 09:05:27 -08003282 // overhead of 40B per packet video produces 2240bps overhead.
3283 // So the encoder BW should be set to 57760bps.
3284 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
michaelta3328772016-11-29 09:25:03 -08003285 {
3286 rtc::CritScope lock(&crit_);
michaelt273f31b2017-02-08 08:21:52 -08003287 EXPECT_LE(max_bitrate_bps_, 57760u);
michaelta3328772016-11-29 09:25:03 -08003288 }
3289 }
3290
3291 private:
3292 Call* call_;
3293 rtc::CriticalSection crit_;
michaelt192132e2017-01-26 09:05:27 -08003294 uint32_t max_bitrate_bps_ GUARDED_BY(&crit_);
3295 bool first_packet_sent_ GUARDED_BY(&crit_);
3296 rtc::Event bitrate_changed_event_;
michaelta3328772016-11-29 09:25:03 -08003297 } test;
3298
3299 RunBaseTest(&test);
3300}
3301
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00003302} // namespace webrtc