blob: 5c836e0f99b61faf33bb75a89890b31a381dc8d6 [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"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000021#include "webrtc/call.h"
Peter Boström5c389d32015-09-25 13:58:30 +020022#include "webrtc/call/transport_adapter.h"
pbosa96b60b2016-04-18 21:12:48 -070023#include "webrtc/common_video/include/frame_callback.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010024#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
25#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +000026#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
pbos@webrtc.org013d9942013-08-22 09:42:17 +000027#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
philipel0f9af012015-09-01 07:01:51 -070028#include "webrtc/modules/rtp_rtcp/source/rtp_format_vp9.h"
philipel7fabd462015-09-03 04:42:32 -070029#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010030#include "webrtc/system_wrappers/include/sleep.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000031#include "webrtc/test/call_test.h"
pbos@webrtc.org709e2972014-03-19 10:59:52 +000032#include "webrtc/test/configurable_frame_size_encoder.h"
Peter Boströmeb66e802015-06-05 11:08:03 +020033#include "webrtc/test/fake_texture_frame.h"
perkja49cbd32016-09-16 07:53:41 -070034#include "webrtc/test/frame_generator.h"
nisse26acec42016-04-15 03:43:39 -070035#include "webrtc/test/frame_utils.h"
kwibergac9f8762016-09-30 22:29:43 -070036#include "webrtc/test/gtest.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000037#include "webrtc/test/null_transport.h"
pbos@webrtc.org709e2972014-03-19 10:59:52 +000038#include "webrtc/test/testsupport/perf_test.h"
perkjfa10b552016-10-02 23:45:26 -070039
pbos@webrtc.org273a4142014-12-01 15:23:21 +000040#include "webrtc/video/send_statistics_proxy.h"
Thiago Farina9bfe3da2015-04-10 12:52:13 +020041#include "webrtc/video_frame.h"
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000042#include "webrtc/video_send_stream.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000043
44namespace webrtc {
45
sprang@webrtc.org346094c2014-02-18 08:40:33 +000046enum VideoFormat { kGeneric, kVP8, };
47
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070048void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
49 const std::vector<VideoFrame>& frames2);
50VideoFrame CreateVideoFrame(int width, int height, uint8_t data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +000051
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000052class VideoSendStreamTest : public test::CallTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000053 protected:
stefan@webrtc.org69969e22013-11-15 12:32:15 +000054 void TestNackRetransmission(uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +000055 uint8_t retransmit_payload_type);
sprang@webrtc.org346094c2014-02-18 08:40:33 +000056 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
Åsa Perssonff24c042015-12-04 10:58:08 +010057
58 void TestVp9NonFlexMode(uint8_t num_temporal_layers,
59 uint8_t num_spatial_layers);
perkj803d97f2016-11-01 11:45:46 -070060
61 void TestRequestSourceRotateVideo(bool support_orientation_ext);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000062};
63
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000064TEST_F(VideoSendStreamTest, CanStartStartedStream) {
skvlad11a9cbf2016-10-07 11:53:05 -070065 CreateSenderCall(Call::Config(&event_log_));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000066
solenberg4fbae2b2015-08-28 04:07:10 -070067 test::NullTransport transport;
Stefan Holmer9fea80f2016-01-07 17:43:18 +010068 CreateSendConfig(1, 0, &transport);
69 CreateVideoStreams();
stefanff483612015-12-21 03:14:00 -080070 video_send_stream_->Start();
71 video_send_stream_->Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000072 DestroyStreams();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000073}
74
75TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
skvlad11a9cbf2016-10-07 11:53:05 -070076 CreateSenderCall(Call::Config(&event_log_));
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000077
solenberg4fbae2b2015-08-28 04:07:10 -070078 test::NullTransport transport;
Stefan Holmer9fea80f2016-01-07 17:43:18 +010079 CreateSendConfig(1, 0, &transport);
80 CreateVideoStreams();
stefanff483612015-12-21 03:14:00 -080081 video_send_stream_->Stop();
82 video_send_stream_->Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000083 DestroyStreams();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000084}
85
pbos@webrtc.org013d9942013-08-22 09:42:17 +000086TEST_F(VideoSendStreamTest, SupportsCName) {
87 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000088 class CNameObserver : public test::SendTest {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000089 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000090 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
pbos@webrtc.org013d9942013-08-22 09:42:17 +000091
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000092 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000093 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org013d9942013-08-22 09:42:17 +000094 RTCPUtility::RTCPParserV2 parser(packet, length, true);
95 EXPECT_TRUE(parser.IsValid());
96
97 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
Erik Språng242e22b2015-05-11 10:17:43 +020098 while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) {
99 if (packet_type == RTCPUtility::RTCPPacketTypes::kSdesChunk) {
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000100 EXPECT_EQ(parser.Packet().CName.CName, kCName);
Peter Boström5811a392015-12-10 13:02:50 +0100101 observation_complete_.Set();
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000102 }
103
104 packet_type = parser.Iterate();
105 }
106
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000107 return SEND_PACKET;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000108 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000109
stefanff483612015-12-21 03:14:00 -0800110 void ModifyVideoConfigs(
111 VideoSendStream::Config* send_config,
112 std::vector<VideoReceiveStream::Config>* receive_configs,
113 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000114 send_config->rtp.c_name = kCName;
115 }
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000116
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000117 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100118 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP with CNAME.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000119 }
120 } test;
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000121
stefane74eef12016-01-08 06:47:13 -0800122 RunBaseTest(&test);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000123}
124
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000125TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000126 class AbsoluteSendTimeObserver : public test::SendTest {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000127 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000128 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000129 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer4654d202015-12-08 09:10:43 +0100130 kRtpExtensionAbsoluteSendTime, test::kAbsSendTimeExtensionId));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000131 }
132
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000133 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000134 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000135 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000136
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000137 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
138 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
139 EXPECT_EQ(header.extension.transmissionTimeOffset, 0);
skvladc3f35152016-09-02 13:23:46 -0700140 if (header.extension.absoluteSendTime != 0) {
141 // Wait for at least one packet with a non-zero send time. The send time
142 // is a 16-bit value derived from the system clock, and it is valid
143 // for a packet to have a zero send time. To tell that from an
144 // unpopulated value we'll wait for a packet with non-zero send time.
145 observation_complete_.Set();
146 } else {
147 LOG(LS_WARNING) << "Got a packet with zero absoluteSendTime, waiting"
148 " for another packet...";
149 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000150
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000151 return SEND_PACKET;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000152 }
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000153
stefanff483612015-12-21 03:14:00 -0800154 void ModifyVideoConfigs(
155 VideoSendStream::Config* send_config,
156 std::vector<VideoReceiveStream::Config>* receive_configs,
157 VideoEncoderConfig* encoder_config) override {
Erik Språng95261872015-04-10 11:58:49 +0200158 send_config->rtp.extensions.clear();
Stefan Holmer4654d202015-12-08 09:10:43 +0100159 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700160 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000161 }
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +0000162
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000163 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100164 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000165 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000166 } test;
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000167
stefane74eef12016-01-08 06:47:13 -0800168 RunBaseTest(&test);
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000169}
170
pbos@webrtc.org29023282013-09-11 10:14:56 +0000171TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000172 static const int kEncodeDelayMs = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000173 class TransmissionTimeOffsetObserver : public test::SendTest {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000174 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000175 TransmissionTimeOffsetObserver()
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000176 : SendTest(kDefaultTimeoutMs),
177 encoder_(Clock::GetRealTimeClock(), kEncodeDelayMs) {
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000178 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
Stefan Holmer12952972015-10-29 15:13:24 +0100179 kRtpExtensionTransmissionTimeOffset, test::kTOffsetExtensionId));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000180 }
181
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000182 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000183 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org29023282013-09-11 10:14:56 +0000184 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000185 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org29023282013-09-11 10:14:56 +0000186
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000187 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
188 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000189 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000190 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
Peter Boström5811a392015-12-10 13:02:50 +0100191 observation_complete_.Set();
pbos@webrtc.org29023282013-09-11 10:14:56 +0000192
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000193 return SEND_PACKET;
pbos@webrtc.org29023282013-09-11 10:14:56 +0000194 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000195
stefanff483612015-12-21 03:14:00 -0800196 void ModifyVideoConfigs(
197 VideoSendStream::Config* send_config,
198 std::vector<VideoReceiveStream::Config>* receive_configs,
199 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000200 send_config->encoder_settings.encoder = &encoder_;
Stefan Holmer12952972015-10-29 15:13:24 +0100201 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700202 send_config->rtp.extensions.push_back(RtpExtension(
203 RtpExtension::kTimestampOffsetUri, test::kTOffsetExtensionId));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000204 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000205
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000206 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100207 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000208 }
pbos@webrtc.org29023282013-09-11 10:14:56 +0000209
asapersson@webrtc.org049e4ec2014-11-20 10:19:46 +0000210 test::DelayedEncoder encoder_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000211 } test;
212
stefane74eef12016-01-08 06:47:13 -0800213 RunBaseTest(&test);
pbos@webrtc.org29023282013-09-11 10:14:56 +0000214}
215
sprang867fb522015-08-03 04:38:41 -0700216TEST_F(VideoSendStreamTest, SupportsTransportWideSequenceNumbers) {
danilchap42ca68a2016-10-31 03:34:40 -0700217 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
sprang867fb522015-08-03 04:38:41 -0700218 class TransportWideSequenceNumberObserver : public test::SendTest {
219 public:
220 TransportWideSequenceNumberObserver()
221 : SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) {
222 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
223 kRtpExtensionTransportSequenceNumber, kExtensionId));
224 }
225
226 private:
227 Action OnSendRtp(const uint8_t* packet, size_t length) override {
228 RTPHeader header;
229 EXPECT_TRUE(parser_->Parse(packet, length, &header));
230
231 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
232 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset);
233 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
234
Peter Boström5811a392015-12-10 13:02:50 +0100235 observation_complete_.Set();
sprang867fb522015-08-03 04:38:41 -0700236
237 return SEND_PACKET;
238 }
239
stefanff483612015-12-21 03:14:00 -0800240 void ModifyVideoConfigs(
241 VideoSendStream::Config* send_config,
242 std::vector<VideoReceiveStream::Config>* receive_configs,
243 VideoEncoderConfig* encoder_config) override {
sprang867fb522015-08-03 04:38:41 -0700244 send_config->encoder_settings.encoder = &encoder_;
Stefan Holmer12952972015-10-29 15:13:24 +0100245 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -0700246 send_config->rtp.extensions.push_back(RtpExtension(
247 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
sprang867fb522015-08-03 04:38:41 -0700248 }
249
250 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100251 EXPECT_TRUE(Wait()) << "Timed out while waiting for a single RTP packet.";
sprang867fb522015-08-03 04:38:41 -0700252 }
253
254 test::FakeEncoder encoder_;
255 } test;
256
stefane74eef12016-01-08 06:47:13 -0800257 RunBaseTest(&test);
sprang867fb522015-08-03 04:38:41 -0700258}
259
perkj803d97f2016-11-01 11:45:46 -0700260TEST_F(VideoSendStreamTest, SupportsVideoRotation) {
261 class VideoRotationObserver : public test::SendTest {
262 public:
263 VideoRotationObserver() : SendTest(kDefaultTimeoutMs) {
264 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
265 kRtpExtensionVideoRotation, test::kVideoRotationExtensionId));
266 }
267
268 Action OnSendRtp(const uint8_t* packet, size_t length) override {
269 RTPHeader header;
270 EXPECT_TRUE(parser_->Parse(packet, length, &header));
271 EXPECT_TRUE(header.extension.hasVideoRotation);
272 EXPECT_EQ(kVideoRotation_90, header.extension.videoRotation);
273 observation_complete_.Set();
274 return SEND_PACKET;
275 }
276
277 void ModifyVideoConfigs(
278 VideoSendStream::Config* send_config,
279 std::vector<VideoReceiveStream::Config>* receive_configs,
280 VideoEncoderConfig* encoder_config) override {
281 send_config->rtp.extensions.clear();
282 send_config->rtp.extensions.push_back(RtpExtension(
283 RtpExtension::kVideoRotationUri, test::kVideoRotationExtensionId));
284 }
285
286 void OnFrameGeneratorCapturerCreated(
287 test::FrameGeneratorCapturer* frame_generator_capturer) override {
288 frame_generator_capturer->SetFakeRotation(kVideoRotation_90);
289 }
290
291 void PerformTest() override {
292 EXPECT_TRUE(Wait()) << "Timed out while waiting for single RTP packet.";
293 }
294 } test;
295
296 RunBaseTest(&test);
297}
298
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000299class FakeReceiveStatistics : public NullReceiveStatistics {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000300 public:
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000301 FakeReceiveStatistics(uint32_t send_ssrc,
302 uint32_t last_sequence_number,
303 uint32_t cumulative_lost,
304 uint8_t fraction_lost)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000305 : lossy_stats_(new LossyStatistician(last_sequence_number,
306 cumulative_lost,
307 fraction_lost)) {
308 stats_map_[send_ssrc] = lossy_stats_.get();
309 }
310
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000311 StatisticianMap GetActiveStatisticians() const override { return stats_map_; }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000312
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000313 StreamStatistician* GetStatistician(uint32_t ssrc) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000314 return lossy_stats_.get();
315 }
316
317 private:
318 class LossyStatistician : public StreamStatistician {
319 public:
320 LossyStatistician(uint32_t extended_max_sequence_number,
321 uint32_t cumulative_lost,
322 uint8_t fraction_lost) {
323 stats_.fraction_lost = fraction_lost;
324 stats_.cumulative_lost = cumulative_lost;
325 stats_.extended_max_sequence_number = extended_max_sequence_number;
326 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000327 bool GetStatistics(RtcpStatistics* statistics, bool reset) override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000328 *statistics = stats_;
329 return true;
330 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000331 void GetDataCounters(size_t* bytes_received,
332 uint32_t* packets_received) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000333 *bytes_received = 0;
334 *packets_received = 0;
335 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000336 void GetReceiveStreamDataCounters(
337 StreamDataCounters* data_counters) const override {}
338 uint32_t BitrateReceived() const override { return 0; }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000339 bool IsRetransmitOfOldPacket(const RTPHeader& header,
340 int64_t min_rtt) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000341 return false;
342 }
343
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000344 bool IsPacketInOrder(uint16_t sequence_number) const override {
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000345 return true;
346 }
sprang@webrtc.org54ae4ff2013-12-19 13:26:02 +0000347
348 RtcpStatistics stats_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000349 };
350
kwiberg27f982b2016-03-01 11:52:33 -0800351 std::unique_ptr<LossyStatistician> lossy_stats_;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000352 StatisticianMap stats_map_;
353};
354
brandtre602f0a2016-10-31 03:40:49 -0700355class UlpfecObserver : public test::EndToEndTest {
Stefan Holmer4654d202015-12-08 09:10:43 +0100356 public:
brandtre602f0a2016-10-31 03:40:49 -0700357 UlpfecObserver(bool header_extensions_enabled,
Peter Boström39593972016-02-15 11:27:15 +0100358 bool use_nack,
359 bool expect_red,
brandtre602f0a2016-10-31 03:40:49 -0700360 bool expect_ulpfec,
Peter Boström39593972016-02-15 11:27:15 +0100361 const std::string& codec)
362 : EndToEndTest(VideoSendStreamTest::kDefaultTimeoutMs),
363 payload_name_(codec),
364 use_nack_(use_nack),
365 expect_red_(expect_red),
brandtre602f0a2016-10-31 03:40:49 -0700366 expect_ulpfec_(expect_ulpfec),
Stefan Holmer4654d202015-12-08 09:10:43 +0100367 send_count_(0),
368 received_media_(false),
369 received_fec_(false),
Peter Boström39593972016-02-15 11:27:15 +0100370 header_extensions_enabled_(header_extensions_enabled) {
371 if (codec == "H264") {
372 encoder_.reset(new test::FakeH264Encoder(Clock::GetRealTimeClock()));
373 } else if (codec == "VP8") {
374 encoder_.reset(VideoEncoder::Create(VideoEncoder::EncoderType::kVp8));
375 } else if (codec == "VP9") {
376 encoder_.reset(VideoEncoder::Create(VideoEncoder::EncoderType::kVp9));
377 } else {
378 RTC_NOTREACHED();
379 }
380 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100381
382 private:
383 Action OnSendRtp(const uint8_t* packet, size_t length) override {
384 RTPHeader header;
385 EXPECT_TRUE(parser_->Parse(packet, length, &header));
386
Peter Boström39593972016-02-15 11:27:15 +0100387 ++send_count_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100388 int encapsulated_payload_type = -1;
389 if (header.payloadType == VideoSendStreamTest::kRedPayloadType) {
Peter Boström39593972016-02-15 11:27:15 +0100390 EXPECT_TRUE(expect_red_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100391 encapsulated_payload_type = static_cast<int>(packet[header.headerLength]);
392 if (encapsulated_payload_type !=
Peter Boström39593972016-02-15 11:27:15 +0100393 VideoSendStreamTest::kFakeVideoSendPayloadType) {
Stefan Holmer4654d202015-12-08 09:10:43 +0100394 EXPECT_EQ(VideoSendStreamTest::kUlpfecPayloadType,
395 encapsulated_payload_type);
Peter Boström39593972016-02-15 11:27:15 +0100396 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100397 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100398 EXPECT_EQ(VideoSendStreamTest::kFakeVideoSendPayloadType,
399 header.payloadType);
Peter Boström39593972016-02-15 11:27:15 +0100400 if (static_cast<size_t>(header.headerLength + header.paddingLength) <
401 length) {
402 // Not padding-only, media received outside of RED.
403 EXPECT_FALSE(expect_red_);
404 received_media_ = true;
405 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100406 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000407
Stefan Holmer4654d202015-12-08 09:10:43 +0100408 if (header_extensions_enabled_) {
409 EXPECT_TRUE(header.extension.hasAbsoluteSendTime);
410 uint32_t kHalf24BitsSpace = 0xFFFFFF / 2;
411 if (header.extension.absoluteSendTime <= kHalf24BitsSpace &&
412 prev_header_.extension.absoluteSendTime > kHalf24BitsSpace) {
413 // 24 bits wrap.
414 EXPECT_GT(prev_header_.extension.absoluteSendTime,
415 header.extension.absoluteSendTime);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000416 } else {
Stefan Holmer4654d202015-12-08 09:10:43 +0100417 EXPECT_GE(header.extension.absoluteSendTime,
418 prev_header_.extension.absoluteSendTime);
Stefan Holmer01b48882015-05-05 10:21:24 +0200419 }
Stefan Holmer4654d202015-12-08 09:10:43 +0100420 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
421 uint16_t seq_num_diff = header.extension.transportSequenceNumber -
422 prev_header_.extension.transportSequenceNumber;
423 EXPECT_EQ(1, seq_num_diff);
424 }
Stefan Holmer01b48882015-05-05 10:21:24 +0200425
Stefan Holmer4654d202015-12-08 09:10:43 +0100426 if (encapsulated_payload_type != -1) {
427 if (encapsulated_payload_type ==
428 VideoSendStreamTest::kUlpfecPayloadType) {
brandtre602f0a2016-10-31 03:40:49 -0700429 EXPECT_TRUE(expect_ulpfec_);
Stefan Holmer4654d202015-12-08 09:10:43 +0100430 received_fec_ = true;
431 } else {
432 received_media_ = true;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000433 }
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000434 }
435
Peter Boström39593972016-02-15 11:27:15 +0100436 if (send_count_ > 100 && received_media_) {
brandtre602f0a2016-10-31 03:40:49 -0700437 if (received_fec_ || !expect_ulpfec_)
Peter Boström39593972016-02-15 11:27:15 +0100438 observation_complete_.Set();
439 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000440
Stefan Holmer4654d202015-12-08 09:10:43 +0100441 prev_header_ = header;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000442
Stefan Holmer4654d202015-12-08 09:10:43 +0100443 return SEND_PACKET;
444 }
445
Peter Boström39593972016-02-15 11:27:15 +0100446 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
447 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
448 // Configure some network delay.
449 const int kNetworkDelayMs = 100;
450 FakeNetworkPipe::Config config;
451 config.loss_percent = 50;
452 config.queue_delay_ms = kNetworkDelayMs;
453 return new test::PacketTransport(sender_call, this,
454 test::PacketTransport::kSender, config);
455 }
456
stefanff483612015-12-21 03:14:00 -0800457 void ModifyVideoConfigs(
458 VideoSendStream::Config* send_config,
459 std::vector<VideoReceiveStream::Config>* receive_configs,
460 VideoEncoderConfig* encoder_config) override {
Stefan Holmer4654d202015-12-08 09:10:43 +0100461 transport_adapter_.reset(
462 new internal::TransportAdapter(send_config->send_transport));
463 transport_adapter_->Enable();
Peter Boström39593972016-02-15 11:27:15 +0100464 if (use_nack_) {
465 send_config->rtp.nack.rtp_history_ms =
466 (*receive_configs)[0].rtp.nack.rtp_history_ms =
467 VideoSendStreamTest::kNackRtpHistoryMs;
468 }
469 send_config->encoder_settings.encoder = encoder_.get();
470 send_config->encoder_settings.payload_name = payload_name_;
brandtrb5f2c3f2016-10-04 23:28:39 -0700471 send_config->rtp.ulpfec.red_payload_type =
472 VideoSendStreamTest::kRedPayloadType;
473 send_config->rtp.ulpfec.ulpfec_payload_type =
474 VideoSendStreamTest::kUlpfecPayloadType;
Stefan Holmer4654d202015-12-08 09:10:43 +0100475 if (header_extensions_enabled_) {
476 send_config->rtp.extensions.push_back(RtpExtension(
isheriff6f8d6862016-05-26 11:24:55 -0700477 RtpExtension::kAbsSendTimeUri, test::kAbsSendTimeExtensionId));
Stefan Holmer4654d202015-12-08 09:10:43 +0100478 send_config->rtp.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700479 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
Stefan Holmer4654d202015-12-08 09:10:43 +0100480 test::kTransportSequenceNumberExtensionId));
481 }
brandtrb5f2c3f2016-10-04 23:28:39 -0700482 (*receive_configs)[0].rtp.ulpfec.red_payload_type =
483 send_config->rtp.ulpfec.red_payload_type;
484 (*receive_configs)[0].rtp.ulpfec.ulpfec_payload_type =
485 send_config->rtp.ulpfec.ulpfec_payload_type;
Stefan Holmer4654d202015-12-08 09:10:43 +0100486 }
487
488 void PerformTest() override {
489 EXPECT_TRUE(Wait()) << "Timed out waiting for FEC and media packets.";
490 }
491
kwiberg27f982b2016-03-01 11:52:33 -0800492 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
493 std::unique_ptr<VideoEncoder> encoder_;
Peter Boström39593972016-02-15 11:27:15 +0100494 const std::string payload_name_;
495 const bool use_nack_;
496 const bool expect_red_;
brandtre602f0a2016-10-31 03:40:49 -0700497 const bool expect_ulpfec_;
Stefan Holmer4654d202015-12-08 09:10:43 +0100498 int send_count_;
499 bool received_media_;
500 bool received_fec_;
501 bool header_extensions_enabled_;
502 RTPHeader prev_header_;
503};
504
brandtre602f0a2016-10-31 03:40:49 -0700505TEST_F(VideoSendStreamTest, SupportsUlpfecWithExtensions) {
506 UlpfecObserver test(true, false, true, true, "VP8");
stefane74eef12016-01-08 06:47:13 -0800507 RunBaseTest(&test);
Stefan Holmer4654d202015-12-08 09:10:43 +0100508}
509
brandtre602f0a2016-10-31 03:40:49 -0700510TEST_F(VideoSendStreamTest, SupportsUlpfecWithoutExtensions) {
511 UlpfecObserver test(false, false, true, true, "VP8");
Peter Boström39593972016-02-15 11:27:15 +0100512 RunBaseTest(&test);
513}
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000514
Peter Boström39593972016-02-15 11:27:15 +0100515// The FEC scheme used is not efficient for H264, so we should not use RED/FEC
516// since we'll still have to re-request FEC packets, effectively wasting
517// bandwidth since the receiver has to wait for FEC retransmissions to determine
518// that the received state is actually decodable.
brandtre602f0a2016-10-31 03:40:49 -0700519TEST_F(VideoSendStreamTest, DoesNotUtilizeUlpfecForH264WithNackEnabled) {
520 UlpfecObserver test(false, true, true, false, "H264");
Peter Boström39593972016-02-15 11:27:15 +0100521 RunBaseTest(&test);
522}
523
524// Without retransmissions FEC for H264 is fine.
525TEST_F(VideoSendStreamTest, DoesUtilizeRedForH264WithoutNackEnabled) {
brandtre602f0a2016-10-31 03:40:49 -0700526 UlpfecObserver test(false, false, true, true, "H264");
Peter Boström39593972016-02-15 11:27:15 +0100527 RunBaseTest(&test);
528}
529
530TEST_F(VideoSendStreamTest, DoesUtilizeRedForVp8WithNackEnabled) {
brandtre602f0a2016-10-31 03:40:49 -0700531 UlpfecObserver test(false, true, true, true, "VP8");
Peter Boström39593972016-02-15 11:27:15 +0100532 RunBaseTest(&test);
533}
534
Peter Boström12996152016-05-14 02:03:18 +0200535#if !defined(RTC_DISABLE_VP9)
Peter Boström39593972016-02-15 11:27:15 +0100536TEST_F(VideoSendStreamTest, DoesUtilizeRedForVp9WithNackEnabled) {
brandtre602f0a2016-10-31 03:40:49 -0700537 UlpfecObserver test(false, true, true, true, "VP9");
stefane74eef12016-01-08 06:47:13 -0800538 RunBaseTest(&test);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000539}
Peter Boström12996152016-05-14 02:03:18 +0200540#endif // !defined(RTC_DISABLE_VP9)
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000541
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000542void VideoSendStreamTest::TestNackRetransmission(
543 uint32_t retransmit_ssrc,
stefan@webrtc.orgcb254aa2014-06-12 15:12:25 +0000544 uint8_t retransmit_payload_type) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000545 class NackObserver : public test::SendTest {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000546 public:
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000547 explicit NackObserver(uint32_t retransmit_ssrc,
548 uint8_t retransmit_payload_type)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000549 : SendTest(kDefaultTimeoutMs),
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000550 send_count_(0),
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000551 retransmit_ssrc_(retransmit_ssrc),
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000552 retransmit_payload_type_(retransmit_payload_type),
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000553 nacked_sequence_number_(-1) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +0000554 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000555
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000556 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000557 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000558 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000559 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000560
561 // Nack second packet after receiving the third one.
562 if (++send_count_ == 3) {
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000563 uint16_t nack_sequence_number = header.sequenceNumber - 1;
564 nacked_sequence_number_ = nack_sequence_number;
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000565 NullReceiveStatistics null_stats;
Peter Boströmac547a62015-09-17 23:03:57 +0200566 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(), &null_stats,
terelius429c3452016-01-21 05:42:04 -0800567 nullptr, nullptr, transport_adapter_.get());
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000568
pbosda903ea2015-10-02 02:36:56 -0700569 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100570 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
pbos@webrtc.org0e63e762013-09-20 11:56:26 +0000571
572 RTCPSender::FeedbackState feedback_state;
573
574 EXPECT_EQ(0,
575 rtcp_sender.SendRTCP(
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000576 feedback_state, kRtcpNack, 1, &nack_sequence_number));
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000577 }
578
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000579 uint16_t sequence_number = header.sequenceNumber;
580
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000581 if (header.ssrc == retransmit_ssrc_ &&
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100582 retransmit_ssrc_ != kVideoSendSsrcs[0]) {
583 // Not kVideoSendSsrcs[0], assume correct RTX packet. Extract sequence
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000584 // number.
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000585 const uint8_t* rtx_header = packet + header.headerLength;
586 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
587 }
588
589 if (sequence_number == nacked_sequence_number_) {
590 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000591 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
Peter Boström5811a392015-12-10 13:02:50 +0100592 observation_complete_.Set();
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000593 }
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000594
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000595 return SEND_PACKET;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000596 }
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000597
stefanff483612015-12-21 03:14:00 -0800598 void ModifyVideoConfigs(
599 VideoSendStream::Config* send_config,
600 std::vector<VideoReceiveStream::Config>* receive_configs,
601 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700602 transport_adapter_.reset(
603 new internal::TransportAdapter(send_config->send_transport));
604 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000605 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000606 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100607 if (retransmit_ssrc_ != kVideoSendSsrcs[0])
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000608 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
609 }
610
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000611 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100612 EXPECT_TRUE(Wait()) << "Timed out while waiting for NACK retransmission.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000613 }
614
kwiberg27f982b2016-03-01 11:52:33 -0800615 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000616 int send_count_;
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000617 uint32_t retransmit_ssrc_;
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000618 uint8_t retransmit_payload_type_;
pbos@webrtc.orge7223e72014-01-23 16:14:34 +0000619 int nacked_sequence_number_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000620 } test(retransmit_ssrc, retransmit_payload_type);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000621
stefane74eef12016-01-08 06:47:13 -0800622 RunBaseTest(&test);
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000623}
624
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000625TEST_F(VideoSendStreamTest, RetransmitsNack) {
626 // Normal NACKs should use the send SSRC.
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100627 TestNackRetransmission(kVideoSendSsrcs[0], kFakeVideoSendPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000628}
629
630TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
631 // NACKs over RTX should use a separate SSRC.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000632 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
pbos@webrtc.org5860de02013-09-16 13:01:47 +0000633}
634
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000635void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
636 bool with_fec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000637 // Use a fake encoder to output a frame of every size in the range [90, 290],
638 // for each size making sure that the exact number of payload bytes received
639 // is correct and that packets are fragmented to respect max packet size.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000640 static const size_t kMaxPacketSize = 128;
641 static const size_t start = 90;
642 static const size_t stop = 290;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000643
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000644 // Observer that verifies that the expected number of packets and bytes
645 // arrive for each frame size, from start_size to stop_size.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000646 class FrameFragmentationTest : public test::SendTest,
647 public EncodedFrameObserver {
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000648 public:
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000649 FrameFragmentationTest(size_t max_packet_size,
650 size_t start_size,
651 size_t stop_size,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000652 bool test_generic_packetization,
653 bool use_fec)
654 : SendTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000655 encoder_(stop),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000656 max_packet_size_(max_packet_size),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000657 stop_size_(stop_size),
658 test_generic_packetization_(test_generic_packetization),
659 use_fec_(use_fec),
660 packet_count_(0),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000661 accumulated_size_(0),
662 accumulated_payload_(0),
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000663 fec_packet_received_(false),
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000664 current_size_rtp_(start_size),
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000665 current_size_frame_(static_cast<int32_t>(start_size)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000666 // Fragmentation required, this test doesn't make sense without it.
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000667 encoder_.SetFrameSize(start_size);
henrikg91d6ede2015-09-17 00:24:34 -0700668 RTC_DCHECK_GT(stop_size, max_packet_size);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000669 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000670
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000671 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000672 Action OnSendRtp(const uint8_t* packet, size_t size) override {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000673 size_t length = size;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000674 RTPHeader header;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000675 EXPECT_TRUE(parser_->Parse(packet, length, &header));
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000676
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000677 EXPECT_LE(length, max_packet_size_);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000678
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000679 if (use_fec_) {
680 uint8_t payload_type = packet[header.headerLength];
681 bool is_fec = header.payloadType == kRedPayloadType &&
682 payload_type == kUlpfecPayloadType;
683 if (is_fec) {
684 fec_packet_received_ = true;
685 return SEND_PACKET;
686 }
687 }
688
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000689 accumulated_size_ += length;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000690
691 if (use_fec_)
692 TriggerLossReport(header);
693
694 if (test_generic_packetization_) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200695 size_t overhead = header.headerLength + header.paddingLength;
696 // Only remove payload header and RED header if the packet actually
697 // contains payload.
698 if (length > overhead) {
699 overhead += (1 /* Generic header */);
700 if (use_fec_)
701 overhead += 1; // RED for FEC header.
702 }
703 EXPECT_GE(length, overhead);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000704 accumulated_payload_ += length - overhead;
705 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000706
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000707 // Marker bit set indicates last packet of a frame.
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000708 if (header.markerBit) {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000709 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
710 // With FEC enabled, frame size is incremented asynchronously, so
711 // "old" frames one byte too small may arrive. Accept, but don't
712 // increase expected frame size.
713 accumulated_size_ = 0;
714 accumulated_payload_ = 0;
715 return SEND_PACKET;
716 }
717
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000718 EXPECT_GE(accumulated_size_, current_size_rtp_);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000719 if (test_generic_packetization_) {
720 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
721 }
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000722
723 // Last packet of frame; reset counters.
724 accumulated_size_ = 0;
725 accumulated_payload_ = 0;
726 if (current_size_rtp_ == stop_size_) {
727 // Done! (Don't increase size again, might arrive more @ stop_size).
Peter Boström5811a392015-12-10 13:02:50 +0100728 observation_complete_.Set();
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000729 } else {
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000730 // Increase next expected frame size. If testing with FEC, make sure
731 // a FEC packet has been received for this frame size before
732 // proceeding, to make sure that redundancy packets don't exceed
733 // size limit.
734 if (!use_fec_) {
735 ++current_size_rtp_;
736 } else if (fec_packet_received_) {
737 fec_packet_received_ = false;
738 ++current_size_rtp_;
739 ++current_size_frame_;
740 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000741 }
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000742 }
743
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000744 return SEND_PACKET;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000745 }
746
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000747 void TriggerLossReport(const RTPHeader& header) {
748 // Send lossy receive reports to trigger FEC enabling.
749 if (packet_count_++ % 2 != 0) {
750 // Receive statistics reporting having lost 50% of the packets.
751 FakeReceiveStatistics lossy_receive_stats(
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100752 kVideoSendSsrcs[0], header.sequenceNumber, packet_count_ / 2, 127);
Peter Boströmac547a62015-09-17 23:03:57 +0200753 RTCPSender rtcp_sender(false, Clock::GetRealTimeClock(),
terelius429c3452016-01-21 05:42:04 -0800754 &lossy_receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -0700755 transport_adapter_.get());
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000756
pbosda903ea2015-10-02 02:36:56 -0700757 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100758 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000759
760 RTCPSender::FeedbackState feedback_state;
761
762 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
763 }
764 }
765
nisseef8b61e2016-04-29 06:09:15 -0700766 void EncodedFrameCallback(const EncodedFrame& encoded_frame) override {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000767 // Increase frame size for next encoded frame, in the context of the
768 // encoder thread.
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000769 if (!use_fec_ &&
770 current_size_frame_.Value() < static_cast<int32_t>(stop_size_)) {
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000771 ++current_size_frame_;
772 }
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000773 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_.Value()));
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000774 }
775
Stefan Holmere5904162015-03-26 11:11:06 +0100776 Call::Config GetSenderCallConfig() override {
skvlad11a9cbf2016-10-07 11:53:05 -0700777 Call::Config config(&event_log_);
Stefan Holmere5904162015-03-26 11:11:06 +0100778 const int kMinBitrateBps = 30000;
779 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
780 return config;
781 }
782
stefanff483612015-12-21 03:14:00 -0800783 void ModifyVideoConfigs(
784 VideoSendStream::Config* send_config,
785 std::vector<VideoReceiveStream::Config>* receive_configs,
786 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -0700787 transport_adapter_.reset(
788 new internal::TransportAdapter(send_config->send_transport));
789 transport_adapter_->Enable();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000790 if (use_fec_) {
brandtrb5f2c3f2016-10-04 23:28:39 -0700791 send_config->rtp.ulpfec.red_payload_type = kRedPayloadType;
792 send_config->rtp.ulpfec.ulpfec_payload_type = kUlpfecPayloadType;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000793 }
794
795 if (!test_generic_packetization_)
796 send_config->encoder_settings.payload_name = "VP8";
797
798 send_config->encoder_settings.encoder = &encoder_;
799 send_config->rtp.max_packet_size = kMaxPacketSize;
800 send_config->post_encode_callback = this;
801
Erik Språng95261872015-04-10 11:58:49 +0200802 // Make sure there is at least one extension header, to make the RTP
803 // header larger than the base length of 12 bytes.
804 EXPECT_FALSE(send_config->rtp.extensions.empty());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000805 }
806
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000807 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100808 EXPECT_TRUE(Wait()) << "Timed out while observing incoming RTP packets.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000809 }
810
kwiberg27f982b2016-03-01 11:52:33 -0800811 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000812 test::ConfigurableFrameSizeEncoder encoder_;
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000813
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000814 const size_t max_packet_size_;
815 const size_t stop_size_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000816 const bool test_generic_packetization_;
817 const bool use_fec_;
818
819 uint32_t packet_count_;
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000820 size_t accumulated_size_;
821 size_t accumulated_payload_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000822 bool fec_packet_received_;
823
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000824 size_t current_size_rtp_;
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000825 Atomic32 current_size_frame_;
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000826 };
827
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000828 // Don't auto increment if FEC is used; continue sending frame size until
829 // a FEC packet has been received.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000830 FrameFragmentationTest test(
831 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
sprang@webrtc.org8b881922013-12-10 10:05:17 +0000832
stefane74eef12016-01-08 06:47:13 -0800833 RunBaseTest(&test);
sprang@webrtc.org5d957e22013-10-16 11:37:54 +0000834}
835
sprang@webrtc.org346094c2014-02-18 08:40:33 +0000836// TODO(sprang): Is there any way of speeding up these tests?
837TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
838 TestPacketFragmentationSize(kGeneric, false);
839}
840
841TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
842 TestPacketFragmentationSize(kGeneric, true);
843}
844
845TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
846 TestPacketFragmentationSize(kVP8, false);
847}
848
849TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
850 TestPacketFragmentationSize(kVP8, true);
851}
852
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000853// The test will go through a number of phases.
854// 1. Start sending packets.
855// 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 +0000856// suspend the stream.
857// 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000858// packets.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000859// 4. Signal a high REMB and then wait for the RTP stream to start again.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +0000860// When the stream is detected again, and the stats show that the stream
861// is no longer suspended, the test ends.
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000862TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
863 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000864
nissed30a1112016-04-18 05:15:22 -0700865 class RembObserver : public test::SendTest,
866 public rtc::VideoSinkInterface<VideoFrame> {
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000867 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000868 RembObserver()
869 : SendTest(kDefaultTimeoutMs),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000870 clock_(Clock::GetRealTimeClock()),
Erik Språng737336d2016-07-29 12:59:36 +0200871 stream_(nullptr),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000872 test_state_(kBeforeSuspend),
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000873 rtp_count_(0),
874 last_sequence_number_(0),
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000875 suspended_frame_count_(0),
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +0000876 low_remb_bps_(0),
Erik Språng737336d2016-07-29 12:59:36 +0200877 high_remb_bps_(0) {}
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000878
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000879 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000880 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +0200881 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000882 ++rtp_count_;
883 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000884 EXPECT_TRUE(parser_->Parse(packet, length, &header));
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000885 last_sequence_number_ = header.sequenceNumber;
886
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000887 if (test_state_ == kBeforeSuspend) {
888 // The stream has started. Try to suspend it.
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +0000889 SendRtcpFeedback(low_remb_bps_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000890 test_state_ = kDuringSuspend;
891 } else if (test_state_ == kDuringSuspend) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +0000892 if (header.paddingLength == 0) {
893 // Received non-padding packet during suspension period. Reset the
894 // counter.
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +0000895 suspended_frame_count_ = 0;
896 }
stefanf116bd02015-10-27 08:29:42 -0700897 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000898 } else if (test_state_ == kWaitingForPacket) {
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +0000899 if (header.paddingLength == 0) {
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +0000900 // Non-padding packet observed. Test is almost complete. Will just
901 // have to wait for the stats to change.
902 test_state_ = kWaitingForStats;
903 }
stefanf116bd02015-10-27 08:29:42 -0700904 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +0000905 } else if (test_state_ == kWaitingForStats) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000906 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +0000907 if (stats.suspended == false) {
908 // Stats flipped to false. Test is complete.
Peter Boström5811a392015-12-10 13:02:50 +0100909 observation_complete_.Set();
henrik.lundin@webrtc.org331d4402013-11-21 14:05:40 +0000910 }
stefanf116bd02015-10-27 08:29:42 -0700911 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000912 }
913
stefan@webrtc.org69969e22013-11-15 12:32:15 +0000914 return SEND_PACKET;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000915 }
916
perkj26091b12016-09-01 01:17:40 -0700917 // This method implements the rtc::VideoSinkInterface. This is called when
918 // a frame is provided to the VideoSendStream.
nissed30a1112016-04-18 05:15:22 -0700919 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +0200920 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000921 if (test_state_ == kDuringSuspend &&
922 ++suspended_frame_count_ > kSuspendTimeFrames) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000923 VideoSendStream::Stats stats = stream_->GetStats();
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +0000924 EXPECT_TRUE(stats.suspended);
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +0000925 SendRtcpFeedback(high_remb_bps_);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000926 test_state_ = kWaitingForPacket;
927 }
928 }
929
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000930 void set_low_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200931 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000932 low_remb_bps_ = value;
933 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +0000934
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000935 void set_high_remb_bps(int value) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200936 rtc::CritScope lock(&crit_);
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000937 high_remb_bps_ = value;
938 }
henrik.lundin@webrtc.org1a3a6e52013-10-28 10:16:14 +0000939
stefanff483612015-12-21 03:14:00 -0800940 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000941 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000942 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000943 stream_ = send_stream;
944 }
945
stefanff483612015-12-21 03:14:00 -0800946 void ModifyVideoConfigs(
947 VideoSendStream::Config* send_config,
948 std::vector<VideoReceiveStream::Config>* receive_configs,
949 VideoEncoderConfig* encoder_config) override {
perkjfa10b552016-10-02 23:45:26 -0700950 RTC_DCHECK_EQ(1u, encoder_config->number_of_streams);
stefanf116bd02015-10-27 08:29:42 -0700951 transport_adapter_.reset(
952 new internal::TransportAdapter(send_config->send_transport));
953 transport_adapter_->Enable();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000954 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000955 send_config->pre_encode_callback = this;
956 send_config->suspend_below_min_bitrate = true;
perkjfa10b552016-10-02 23:45:26 -0700957 int min_bitrate_bps =
958 test::DefaultVideoStreamFactory::kDefaultMinBitratePerStream[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000959 set_low_remb_bps(min_bitrate_bps - 10000);
mflodman101f2502016-06-09 17:21:19 +0200960 int threshold_window = std::max(min_bitrate_bps / 10, 20000);
perkjfa10b552016-10-02 23:45:26 -0700961 ASSERT_GT(encoder_config->max_bitrate_bps,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000962 min_bitrate_bps + threshold_window + 5000);
963 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
964 }
965
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000966 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100967 EXPECT_TRUE(Wait()) << "Timed out during suspend-below-min-bitrate test.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000968 }
969
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000970 enum TestState {
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000971 kBeforeSuspend,
972 kDuringSuspend,
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000973 kWaitingForPacket,
henrik.lundin@webrtc.orged8b2812014-03-18 08:43:29 +0000974 kWaitingForStats
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000975 };
976
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000977 virtual void SendRtcpFeedback(int remb_value)
978 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100979 FakeReceiveStatistics receive_stats(kVideoSendSsrcs[0],
980 last_sequence_number_, rtp_count_, 0);
terelius429c3452016-01-21 05:42:04 -0800981 RTCPSender rtcp_sender(false, clock_, &receive_stats, nullptr, nullptr,
stefanf116bd02015-10-27 08:29:42 -0700982 transport_adapter_.get());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000983
pbosda903ea2015-10-02 02:36:56 -0700984 rtcp_sender.SetRTCPStatus(RtcpMode::kReducedSize);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100985 rtcp_sender.SetRemoteSSRC(kVideoSendSsrcs[0]);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000986 if (remb_value > 0) {
987 rtcp_sender.SetREMBStatus(true);
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +0000988 rtcp_sender.SetREMBData(remb_value, std::vector<uint32_t>());
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +0000989 }
990 RTCPSender::FeedbackState feedback_state;
991 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
992 }
993
kwiberg27f982b2016-03-01 11:52:33 -0800994 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000995 Clock* const clock_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000996 VideoSendStream* stream_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000997
Peter Boströmf2f82832015-05-01 13:00:41 +0200998 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000999 TestState test_state_ GUARDED_BY(crit_);
1000 int rtp_count_ GUARDED_BY(crit_);
1001 int last_sequence_number_ GUARDED_BY(crit_);
1002 int suspended_frame_count_ GUARDED_BY(crit_);
1003 int low_remb_bps_ GUARDED_BY(crit_);
1004 int high_remb_bps_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001005 } test;
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001006
stefane74eef12016-01-08 06:47:13 -08001007 RunBaseTest(&test);
henrik.lundin@webrtc.orgba975e22013-10-23 11:04:57 +00001008}
1009
perkj71ee44c2016-06-15 00:47:53 -07001010// This test that padding stops being send after a while if the Camera stops
1011// producing video frames and that padding resumes if the camera restarts.
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001012TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001013 class NoPaddingWhenVideoIsMuted : public test::SendTest {
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001014 public:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001015 NoPaddingWhenVideoIsMuted()
1016 : SendTest(kDefaultTimeoutMs),
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001017 clock_(Clock::GetRealTimeClock()),
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001018 last_packet_time_ms_(-1),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001019 capturer_(nullptr) {
sprang@webrtc.orgd9b95602014-01-27 13:03:02 +00001020 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001021
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001022 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001023 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001024 rtc::CritScope lock(&crit_);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001025 last_packet_time_ms_ = clock_->TimeInMilliseconds();
perkj71ee44c2016-06-15 00:47:53 -07001026
1027 RTPHeader header;
1028 parser_->Parse(packet, length, &header);
1029 const bool only_padding =
1030 header.headerLength + header.paddingLength == length;
1031
1032 if (test_state_ == kBeforeStopCapture) {
1033 capturer_->Stop();
1034 test_state_ = kWaitingForPadding;
1035 } else if (test_state_ == kWaitingForPadding && only_padding) {
1036 test_state_ = kWaitingForNoPackets;
1037 } else if (test_state_ == kWaitingForPaddingAfterCameraRestart &&
1038 only_padding) {
1039 observation_complete_.Set();
1040 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001041 return SEND_PACKET;
1042 }
1043
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001044 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001045 rtc::CritScope lock(&crit_);
perkj71ee44c2016-06-15 00:47:53 -07001046 const int kNoPacketsThresholdMs = 2000;
1047 if (test_state_ == kWaitingForNoPackets &&
1048 (last_packet_time_ms_ > 0 &&
1049 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
1050 kNoPacketsThresholdMs)) {
1051 capturer_->Start();
1052 test_state_ = kWaitingForPaddingAfterCameraRestart;
1053 }
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001054 return SEND_PACKET;
1055 }
1056
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001057 size_t GetNumVideoStreams() const override { return 3; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001058
nisseef8b61e2016-04-29 06:09:15 -07001059 void OnFrameGeneratorCapturerCreated(
1060 test::FrameGeneratorCapturer* frame_generator_capturer) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001061 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001062 capturer_ = frame_generator_capturer;
1063 }
1064
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001065 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001066 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001067 << "Timed out while waiting for RTP packets to stop being sent.";
1068 }
1069
perkj71ee44c2016-06-15 00:47:53 -07001070 enum TestState {
1071 kBeforeStopCapture,
1072 kWaitingForPadding,
1073 kWaitingForNoPackets,
1074 kWaitingForPaddingAfterCameraRestart
1075 };
1076
1077 TestState test_state_ = kBeforeStopCapture;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001078 Clock* const clock_;
kwiberg27f982b2016-03-01 11:52:33 -08001079 std::unique_ptr<internal::TransportAdapter> transport_adapter_;
Peter Boströmf2f82832015-05-01 13:00:41 +02001080 rtc::CriticalSection crit_;
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +00001081 int64_t last_packet_time_ms_ GUARDED_BY(crit_);
1082 test::FrameGeneratorCapturer* capturer_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001083 } test;
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001084
stefane74eef12016-01-08 06:47:13 -08001085 RunBaseTest(&test);
stefan@webrtc.org4ab4fc02013-11-25 11:54:24 +00001086}
1087
isheriffcc5903e2016-10-04 08:29:38 -07001088TEST_F(VideoSendStreamTest, PaddingIsPrimarilyRetransmissions) {
1089 const int kCapacityKbps = 10000; // 10 Mbps
1090 class PaddingIsPrimarilyRetransmissions : public test::EndToEndTest {
1091 public:
1092 PaddingIsPrimarilyRetransmissions()
1093 : EndToEndTest(kDefaultTimeoutMs),
1094 clock_(Clock::GetRealTimeClock()),
1095 padding_length_(0),
1096 total_length_(0),
1097 call_(nullptr) {}
1098
1099 private:
1100 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1101 call_ = sender_call;
1102 }
1103
1104 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1105 rtc::CritScope lock(&crit_);
1106
1107 RTPHeader header;
1108 parser_->Parse(packet, length, &header);
1109 padding_length_ += header.paddingLength;
1110 total_length_ += length;
1111 return SEND_PACKET;
1112 }
1113
1114 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
1115 const int kNetworkDelayMs = 50;
1116 FakeNetworkPipe::Config config;
1117 config.loss_percent = 10;
1118 config.link_capacity_kbps = kCapacityKbps;
1119 config.queue_delay_ms = kNetworkDelayMs;
1120 return new test::PacketTransport(sender_call, this,
1121 test::PacketTransport::kSender, config);
1122 }
1123
1124 void ModifyVideoConfigs(
1125 VideoSendStream::Config* send_config,
1126 std::vector<VideoReceiveStream::Config>* receive_configs,
1127 VideoEncoderConfig* encoder_config) override {
1128 send_config->rtp.extensions.clear();
1129 send_config->rtp.extensions.push_back(
1130 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
1131 test::kTransportSequenceNumberExtensionId));
1132 // Turn on RTX.
1133 send_config->rtp.rtx.payload_type = kFakeVideoSendPayloadType;
1134 send_config->rtp.rtx.ssrcs.push_back(kVideoSendSsrcs[0]);
1135
1136 (*receive_configs)[0].rtp.extensions.clear();
1137 (*receive_configs)[0].rtp.extensions.push_back(
1138 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
1139 test::kTransportSequenceNumberExtensionId));
1140 (*receive_configs)[0].rtp.transport_cc = true;
1141 }
1142
1143 void PerformTest() override {
1144 // TODO(isheriff): Some platforms do not ramp up as expected to full
1145 // capacity due to packet scheduling delays. Fix that before getting
1146 // rid of this.
1147 SleepMs(5000);
1148 {
1149 rtc::CritScope lock(&crit_);
1150 // Expect padding to be a small percentage of total bytes sent.
1151 EXPECT_LT(padding_length_, .1 * total_length_);
1152 }
1153 }
1154
1155 rtc::CriticalSection crit_;
1156 Clock* const clock_;
1157 size_t padding_length_ GUARDED_BY(crit_);
1158 size_t total_length_ GUARDED_BY(crit_);
1159 Call* call_;
1160 } test;
1161
1162 RunBaseTest(&test);
1163}
1164
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001165// This test first observes "high" bitrate use at which point it sends a REMB to
1166// indicate that it should be lowered significantly. The test then observes that
1167// the bitrate observed is sinking well below the min-transmit-bitrate threshold
1168// to verify that the min-transmit bitrate respects incoming REMB.
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001169//
1170// Note that the test starts at "high" bitrate and does not ramp up to "higher"
1171// bitrate since no receiver block or remb is sent in the initial phase.
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001172TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1173 static const int kMinTransmitBitrateBps = 400000;
andresp@webrtc.org44caf012014-03-26 21:00:21 +00001174 static const int kHighBitrateBps = 150000;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001175 static const int kRembBitrateBps = 80000;
1176 static const int kRembRespectedBitrateBps = 100000;
stefanf116bd02015-10-27 08:29:42 -07001177 class BitrateObserver : public test::SendTest {
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001178 public:
1179 BitrateObserver()
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001180 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001181 retranmission_rate_limiter_(Clock::GetRealTimeClock(), 1000),
1182 stream_(nullptr),
1183 bitrate_capped_(false) {}
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001184
1185 private:
nisseef8b61e2016-04-29 06:09:15 -07001186 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001187 if (RtpHeaderParser::IsRtcp(packet, length))
stefanf116bd02015-10-27 08:29:42 -07001188 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001189
1190 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001191 if (!parser_->Parse(packet, length, &header))
stefanf116bd02015-10-27 08:29:42 -07001192 return DROP_PACKET;
Peter Boström74f6e9e2016-04-04 17:56:10 +02001193 RTC_DCHECK(stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001194 VideoSendStream::Stats stats = stream_->GetStats();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001195 if (!stats.substreams.empty()) {
1196 EXPECT_EQ(1u, stats.substreams.size());
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001197 int total_bitrate_bps =
1198 stats.substreams.begin()->second.total_bitrate_bps;
1199 test::PrintResult("bitrate_stats_",
1200 "min_transmit_bitrate_low_remb",
1201 "bitrate_bps",
1202 static_cast<size_t>(total_bitrate_bps),
1203 "bps",
1204 false);
1205 if (total_bitrate_bps > kHighBitrateBps) {
pbos@webrtc.org49ff40e2014-11-13 14:42:37 +00001206 rtp_rtcp_->SetREMBData(kRembBitrateBps,
1207 std::vector<uint32_t>(1, header.ssrc));
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001208 rtp_rtcp_->Process();
1209 bitrate_capped_ = true;
1210 } else if (bitrate_capped_ &&
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001211 total_bitrate_bps < kRembRespectedBitrateBps) {
Peter Boström5811a392015-12-10 13:02:50 +01001212 observation_complete_.Set();
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001213 }
1214 }
stefanf116bd02015-10-27 08:29:42 -07001215 // Packets don't have to be delivered since the test is the receiver.
1216 return DROP_PACKET;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001217 }
1218
stefanff483612015-12-21 03:14:00 -08001219 void OnVideoStreamsCreated(
stefanf116bd02015-10-27 08:29:42 -07001220 VideoSendStream* send_stream,
1221 const std::vector<VideoReceiveStream*>& receive_streams) override {
1222 stream_ = send_stream;
1223 RtpRtcp::Configuration config;
1224 config.outgoing_transport = feedback_transport_.get();
Erik Språng737336d2016-07-29 12:59:36 +02001225 config.retransmission_rate_limiter = &retranmission_rate_limiter_;
stefanf116bd02015-10-27 08:29:42 -07001226 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
1227 rtp_rtcp_->SetREMBStatus(true);
1228 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001229 }
1230
stefanff483612015-12-21 03:14:00 -08001231 void ModifyVideoConfigs(
1232 VideoSendStream::Config* send_config,
1233 std::vector<VideoReceiveStream::Config>* receive_configs,
1234 VideoEncoderConfig* encoder_config) override {
stefanf116bd02015-10-27 08:29:42 -07001235 feedback_transport_.reset(
1236 new internal::TransportAdapter(send_config->send_transport));
1237 feedback_transport_->Enable();
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001238 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001239 }
1240
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001241 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001242 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001243 << "Timeout while waiting for low bitrate stats after REMB.";
1244 }
1245
kwiberg27f982b2016-03-01 11:52:33 -08001246 std::unique_ptr<RtpRtcp> rtp_rtcp_;
1247 std::unique_ptr<internal::TransportAdapter> feedback_transport_;
Erik Språng737336d2016-07-29 12:59:36 +02001248 RateLimiter retranmission_rate_limiter_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001249 VideoSendStream* stream_;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001250 bool bitrate_capped_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001251 } test;
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001252
stefane74eef12016-01-08 06:47:13 -08001253 RunBaseTest(&test);
pbos@webrtc.org709e2972014-03-19 10:59:52 +00001254}
1255
Stefan Holmer280de9e2016-09-30 10:06:51 +02001256TEST_F(VideoSendStreamTest, ChangingNetworkRoute) {
1257 static const int kStartBitrateBps = 300000;
1258 static const int kNewMaxBitrateBps = 1234567;
danilchap42ca68a2016-10-31 03:34:40 -07001259 static const uint8_t kExtensionId = test::kTransportSequenceNumberExtensionId;
Stefan Holmerbe402962016-07-08 16:16:41 +02001260 class ChangingNetworkRouteTest : public test::EndToEndTest {
1261 public:
Stefan Holmerbe402962016-07-08 16:16:41 +02001262 ChangingNetworkRouteTest()
Stefan Holmer280de9e2016-09-30 10:06:51 +02001263 : EndToEndTest(test::CallTest::kDefaultTimeoutMs), call_(nullptr) {
1264 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
1265 kRtpExtensionTransportSequenceNumber, kExtensionId));
1266 }
Stefan Holmerbe402962016-07-08 16:16:41 +02001267
1268 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1269 call_ = sender_call;
1270 }
1271
Stefan Holmer280de9e2016-09-30 10:06:51 +02001272 void ModifyVideoConfigs(
1273 VideoSendStream::Config* send_config,
1274 std::vector<VideoReceiveStream::Config>* receive_configs,
1275 VideoEncoderConfig* encoder_config) override {
1276 send_config->rtp.extensions.clear();
1277 send_config->rtp.extensions.push_back(RtpExtension(
1278 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1279 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1280 (*receive_configs)[0].rtp.transport_cc = true;
1281 }
1282
1283 void ModifyAudioConfigs(
1284 AudioSendStream::Config* send_config,
1285 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1286 send_config->rtp.extensions.clear();
1287 send_config->rtp.extensions.push_back(RtpExtension(
1288 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
1289 (*receive_configs)[0].rtp.extensions.clear();
1290 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1291 (*receive_configs)[0].rtp.transport_cc = true;
1292 }
1293
Stefan Holmerbe402962016-07-08 16:16:41 +02001294 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1295 if (call_->GetStats().send_bandwidth_bps > kStartBitrateBps) {
1296 observation_complete_.Set();
1297 }
1298
1299 return SEND_PACKET;
1300 }
1301
1302 void PerformTest() override {
1303 rtc::NetworkRoute new_route(true, 10, 20, -1);
1304 call_->OnNetworkRouteChanged("transport", new_route);
1305 Call::Config::BitrateConfig bitrate_config;
1306 bitrate_config.start_bitrate_bps = kStartBitrateBps;
1307 call_->SetBitrateConfig(bitrate_config);
1308 EXPECT_TRUE(Wait())
1309 << "Timed out while waiting for start bitrate to be exceeded.";
1310
1311 bitrate_config.start_bitrate_bps = -1;
1312 bitrate_config.max_bitrate_bps = kNewMaxBitrateBps;
1313 call_->SetBitrateConfig(bitrate_config);
1314 // TODO(holmer): We should set the last sent packet id here and verify
1315 // that we correctly ignore any packet loss reported prior to that id.
1316 ++new_route.local_network_id;
1317 call_->OnNetworkRouteChanged("transport", new_route);
stefan01bbc3c2016-10-25 04:19:48 -07001318 EXPECT_GE(call_->GetStats().send_bandwidth_bps, kStartBitrateBps);
Stefan Holmerbe402962016-07-08 16:16:41 +02001319 }
1320
1321 private:
1322 Call* call_;
1323 } test;
1324
1325 RunBaseTest(&test);
1326}
1327
sprang9c0b5512016-07-06 00:54:28 -07001328class MaxPaddingSetTest : public test::SendTest {
1329 public:
1330 static const uint32_t kMinTransmitBitrateBps = 400000;
1331 static const uint32_t kActualEncodeBitrateBps = 40000;
1332 static const uint32_t kMinPacketsToSend = 50;
1333
1334 explicit MaxPaddingSetTest(bool test_switch_content_type)
1335 : SendTest(test::CallTest::kDefaultTimeoutMs),
1336 call_(nullptr),
1337 send_stream_(nullptr),
1338 packets_sent_(0),
1339 running_without_padding_(test_switch_content_type) {}
1340
1341 void OnVideoStreamsCreated(
1342 VideoSendStream* send_stream,
1343 const std::vector<VideoReceiveStream*>& receive_streams) override {
1344 send_stream_ = send_stream;
1345 }
1346
1347 void ModifyVideoConfigs(
1348 VideoSendStream::Config* send_config,
1349 std::vector<VideoReceiveStream::Config>* receive_configs,
1350 VideoEncoderConfig* encoder_config) override {
perkjfa10b552016-10-02 23:45:26 -07001351 RTC_DCHECK_EQ(1u, encoder_config->number_of_streams);
sprang9c0b5512016-07-06 00:54:28 -07001352 if (running_without_padding_) {
1353 encoder_config->min_transmit_bitrate_bps = 0;
1354 encoder_config->content_type =
1355 VideoEncoderConfig::ContentType::kRealtimeVideo;
1356 } else {
1357 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1358 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
1359 }
perkj26091b12016-09-01 01:17:40 -07001360 encoder_config_ = encoder_config->Copy();
sprang9c0b5512016-07-06 00:54:28 -07001361 }
1362
1363 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1364 call_ = sender_call;
1365 }
1366
1367 Action OnSendRtp(const uint8_t* packet, size_t length) override {
1368 rtc::CritScope lock(&crit_);
1369
1370 if (running_without_padding_)
1371 EXPECT_EQ(0, call_->GetStats().max_padding_bitrate_bps);
1372
1373 // Wait until at least kMinPacketsToSend frames have been encoded, so that
1374 // we have reliable data.
1375 if (++packets_sent_ < kMinPacketsToSend)
1376 return SEND_PACKET;
1377
1378 if (running_without_padding_) {
1379 // We've sent kMinPacketsToSend packets with default configuration, switch
1380 // to enabling screen content and setting min transmit bitrate.
1381 packets_sent_ = 0;
1382 encoder_config_.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1383 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
perkj26091b12016-09-01 01:17:40 -07001384 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
sprang9c0b5512016-07-06 00:54:28 -07001385 running_without_padding_ = false;
1386 return SEND_PACKET;
1387 }
1388
1389 // Make sure the pacer has been configured with a min transmit bitrate.
1390 if (call_->GetStats().max_padding_bitrate_bps > 0)
1391 observation_complete_.Set();
1392
1393 return SEND_PACKET;
1394 }
1395
1396 void PerformTest() override {
1397 ASSERT_TRUE(Wait()) << "Timed out waiting for a valid padding bitrate.";
1398 }
1399
1400 private:
1401 rtc::CriticalSection crit_;
1402 Call* call_;
1403 VideoSendStream* send_stream_;
1404 VideoEncoderConfig encoder_config_;
1405 uint32_t packets_sent_ GUARDED_BY(crit_);
1406 bool running_without_padding_;
1407};
1408
1409TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrate) {
1410 MaxPaddingSetTest test(false);
1411 RunBaseTest(&test);
1412}
1413
1414TEST_F(VideoSendStreamTest, RespectsMinTransmitBitrateAfterContentSwitch) {
1415 MaxPaddingSetTest test(true);
1416 RunBaseTest(&test);
1417}
1418
perkjfa10b552016-10-02 23:45:26 -07001419// This test verifies that new frame sizes reconfigures encoders even though not
1420// (yet) sending. The purpose of this is to permit encoding as quickly as
1421// possible once we start sending. Likely the frames being input are from the
1422// same source that will be sent later, which just means that we're ready
1423// earlier.
1424TEST_F(VideoSendStreamTest,
1425 EncoderReconfigureOnResolutionChangeWhenNotSending) {
1426 class EncoderObserver : public test::FakeEncoder {
1427 public:
1428 EncoderObserver()
1429 : FakeEncoder(Clock::GetRealTimeClock()),
1430 init_encode_called_(false, false),
1431 number_of_initializations_(0),
1432 last_initialized_frame_width_(0),
1433 last_initialized_frame_height_(0) {}
1434
1435 void WaitForResolution(int width, int height) {
1436 {
1437 rtc::CritScope lock(&crit_);
1438 if (last_initialized_frame_width_ == width &&
1439 last_initialized_frame_height_ == height) {
1440 return;
1441 }
1442 }
1443 init_encode_called_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1444 {
1445 rtc::CritScope lock(&crit_);
1446 EXPECT_EQ(width, last_initialized_frame_width_);
1447 EXPECT_EQ(height, last_initialized_frame_height_);
1448 }
1449 }
1450
1451 private:
1452 int32_t InitEncode(const VideoCodec* config,
1453 int32_t number_of_cores,
1454 size_t max_payload_size) override {
1455 rtc::CritScope lock(&crit_);
1456 last_initialized_frame_width_ = config->width;
1457 last_initialized_frame_height_ = config->height;
1458 ++number_of_initializations_;
1459 // First time InitEncode is called, the frame size is unknown.
1460 if (number_of_initializations_ > 1)
1461 init_encode_called_.Set();
1462 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1463 }
1464
1465 int32_t Encode(const VideoFrame& input_image,
1466 const CodecSpecificInfo* codec_specific_info,
1467 const std::vector<FrameType>* frame_types) override {
1468 ADD_FAILURE()
1469 << "Unexpected Encode call since the send stream is not started";
1470 return 0;
1471 }
1472
1473 rtc::CriticalSection crit_;
1474 rtc::Event init_encode_called_;
1475 size_t number_of_initializations_ GUARDED_BY(&crit_);
1476 int last_initialized_frame_width_ GUARDED_BY(&crit_);
1477 int last_initialized_frame_height_ GUARDED_BY(&crit_);
1478 };
1479
skvlad11a9cbf2016-10-07 11:53:05 -07001480 CreateSenderCall(Call::Config(&event_log_));
perkjfa10b552016-10-02 23:45:26 -07001481 test::NullTransport transport;
1482 CreateSendConfig(1, 0, &transport);
1483 EncoderObserver encoder;
1484 video_send_config_.encoder_settings.encoder = &encoder;
1485 CreateVideoStreams();
1486 CreateFrameGeneratorCapturer(kDefaultFramerate, kDefaultWidth,
1487 kDefaultHeight);
1488 frame_generator_capturer_->Start();
1489
1490 encoder.WaitForResolution(kDefaultWidth, kDefaultHeight);
1491 frame_generator_capturer_->ChangeResolution(kDefaultWidth * 2,
1492 kDefaultHeight * 2);
1493 encoder.WaitForResolution(kDefaultWidth * 2, kDefaultHeight * 2);
1494 DestroyStreams();
1495}
1496
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001497TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) {
1498 class StartBitrateObserver : public test::FakeEncoder {
1499 public:
1500 StartBitrateObserver()
pbos14fe7082016-04-20 06:35:56 -07001501 : FakeEncoder(Clock::GetRealTimeClock()),
1502 start_bitrate_changed_(false, false),
1503 start_bitrate_kbps_(0) {}
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001504 int32_t InitEncode(const VideoCodec* config,
1505 int32_t number_of_cores,
1506 size_t max_payload_size) override {
1507 rtc::CritScope lock(&crit_);
1508 start_bitrate_kbps_ = config->startBitrate;
pbos14fe7082016-04-20 06:35:56 -07001509 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001510 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1511 }
1512
1513 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1514 rtc::CritScope lock(&crit_);
1515 start_bitrate_kbps_ = new_target_bitrate;
pbos14fe7082016-04-20 06:35:56 -07001516 start_bitrate_changed_.Set();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001517 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1518 }
1519
1520 int GetStartBitrateKbps() const {
1521 rtc::CritScope lock(&crit_);
1522 return start_bitrate_kbps_;
1523 }
1524
pbos14fe7082016-04-20 06:35:56 -07001525 bool WaitForStartBitrate() {
1526 return start_bitrate_changed_.Wait(
1527 VideoSendStreamTest::kDefaultTimeoutMs);
1528 }
1529
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001530 private:
pbos5ad935c2016-01-25 03:52:44 -08001531 rtc::CriticalSection crit_;
pbos14fe7082016-04-20 06:35:56 -07001532 rtc::Event start_bitrate_changed_;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001533 int start_bitrate_kbps_ GUARDED_BY(crit_);
1534 };
1535
skvlad11a9cbf2016-10-07 11:53:05 -07001536 CreateSenderCall(Call::Config(&event_log_));
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001537
solenberg4fbae2b2015-08-28 04:07:10 -07001538 test::NullTransport transport;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001539 CreateSendConfig(1, 0, &transport);
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001540
1541 Call::Config::BitrateConfig bitrate_config;
perkjfa10b552016-10-02 23:45:26 -07001542 bitrate_config.start_bitrate_bps = 2 * video_encoder_config_.max_bitrate_bps;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001543 sender_call_->SetBitrateConfig(bitrate_config);
1544
1545 StartBitrateObserver encoder;
stefanff483612015-12-21 03:14:00 -08001546 video_send_config_.encoder_settings.encoder = &encoder;
perkjfa10b552016-10-02 23:45:26 -07001547 // Since this test does not use a capturer, set |internal_source| = true.
1548 // Encoder configuration is otherwise updated on the next video frame.
1549 video_send_config_.encoder_settings.internal_source = true;
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001550
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001551 CreateVideoStreams();
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001552
pbos14fe7082016-04-20 06:35:56 -07001553 EXPECT_TRUE(encoder.WaitForStartBitrate());
perkjfa10b552016-10-02 23:45:26 -07001554 EXPECT_EQ(video_encoder_config_.max_bitrate_bps / 1000,
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001555 encoder.GetStartBitrateKbps());
1556
perkjfa10b552016-10-02 23:45:26 -07001557 video_encoder_config_.max_bitrate_bps = 2 * bitrate_config.start_bitrate_bps;
perkj26091b12016-09-01 01:17:40 -07001558 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_.Copy());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001559
1560 // New bitrate should be reconfigured above the previous max. As there's no
1561 // network connection this shouldn't be flaky, as no bitrate should've been
1562 // reported in between.
pbos14fe7082016-04-20 06:35:56 -07001563 EXPECT_TRUE(encoder.WaitForStartBitrate());
pbos@webrtc.org143451d2015-03-18 14:40:03 +00001564 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000,
1565 encoder.GetStartBitrateKbps());
1566
1567 DestroyStreams();
1568}
1569
perkj57c21f92016-06-17 07:27:16 -07001570// This test that if the encoder use an internal source, VideoEncoder::SetRates
1571// will be called with zero bitrate during initialization and that
1572// VideoSendStream::Stop also triggers VideoEncoder::SetRates Start to be called
1573// with zero bitrate.
1574TEST_F(VideoSendStreamTest, VideoSendStreamStopSetEncoderRateToZero) {
1575 class StartStopBitrateObserver : public test::FakeEncoder {
1576 public:
1577 StartStopBitrateObserver()
1578 : FakeEncoder(Clock::GetRealTimeClock()),
1579 encoder_init_(false, false),
1580 bitrate_changed_(false, false),
1581 bitrate_kbps_(0) {}
1582 int32_t InitEncode(const VideoCodec* config,
1583 int32_t number_of_cores,
1584 size_t max_payload_size) override {
1585 rtc::CritScope lock(&crit_);
1586 bitrate_kbps_ = config->startBitrate;
1587 encoder_init_.Set();
1588 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1589 }
1590
1591 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
1592 rtc::CritScope lock(&crit_);
1593 bitrate_kbps_ = new_target_bitrate;
1594 bitrate_changed_.Set();
1595 return FakeEncoder::SetRates(new_target_bitrate, framerate);
1596 }
1597
1598 int GetBitrateKbps() const {
1599 rtc::CritScope lock(&crit_);
1600 return bitrate_kbps_;
1601 }
1602
1603 bool WaitForEncoderInit() {
1604 return encoder_init_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1605 }
1606 bool WaitBitrateChanged() {
1607 return bitrate_changed_.Wait(VideoSendStreamTest::kDefaultTimeoutMs);
1608 }
1609
1610 private:
1611 rtc::CriticalSection crit_;
1612 rtc::Event encoder_init_;
1613 rtc::Event bitrate_changed_;
1614 int bitrate_kbps_ GUARDED_BY(crit_);
1615 };
1616
skvlad11a9cbf2016-10-07 11:53:05 -07001617 CreateSenderCall(Call::Config(&event_log_));
perkj57c21f92016-06-17 07:27:16 -07001618
1619 test::NullTransport transport;
1620 CreateSendConfig(1, 0, &transport);
1621
1622 StartStopBitrateObserver encoder;
1623 video_send_config_.encoder_settings.encoder = &encoder;
1624 video_send_config_.encoder_settings.internal_source = true;
1625
1626 CreateVideoStreams();
1627
1628 EXPECT_TRUE(encoder.WaitForEncoderInit());
1629 EXPECT_GT(encoder.GetBitrateKbps(), 0);
1630 video_send_stream_->Start();
1631 EXPECT_TRUE(encoder.WaitBitrateChanged());
1632 EXPECT_GT(encoder.GetBitrateKbps(), 0);
1633 video_send_stream_->Stop();
1634 EXPECT_TRUE(encoder.WaitBitrateChanged());
1635 EXPECT_EQ(0, encoder.GetBitrateKbps());
1636 video_send_stream_->Start();
1637 EXPECT_TRUE(encoder.WaitBitrateChanged());
1638 EXPECT_GT(encoder.GetBitrateKbps(), 0);
1639
1640 DestroyStreams();
1641}
1642
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001643TEST_F(VideoSendStreamTest, CapturesTextureAndVideoFrames) {
nissed30a1112016-04-18 05:15:22 -07001644 class FrameObserver : public rtc::VideoSinkInterface<VideoFrame> {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001645 public:
Peter Boström5811a392015-12-10 13:02:50 +01001646 FrameObserver() : output_frame_event_(false, false) {}
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001647
nissed30a1112016-04-18 05:15:22 -07001648 void OnFrame(const VideoFrame& video_frame) override {
1649 output_frames_.push_back(video_frame);
Peter Boström5811a392015-12-10 13:02:50 +01001650 output_frame_event_.Set();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001651 }
1652
1653 void WaitOutputFrame() {
Peter Boström5811a392015-12-10 13:02:50 +01001654 const int kWaitFrameTimeoutMs = 3000;
1655 EXPECT_TRUE(output_frame_event_.Wait(kWaitFrameTimeoutMs))
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001656 << "Timeout while waiting for output frames.";
1657 }
1658
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001659 const std::vector<VideoFrame>& output_frames() const {
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001660 return output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001661 }
1662
1663 private:
1664 // Delivered output frames.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001665 std::vector<VideoFrame> output_frames_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001666
1667 // Indicate an output frame has arrived.
Peter Boström5811a392015-12-10 13:02:50 +01001668 rtc::Event output_frame_event_;
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001669 };
1670
1671 // Initialize send stream.
skvlad11a9cbf2016-10-07 11:53:05 -07001672 CreateSenderCall(Call::Config(&event_log_));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001673
solenberg4fbae2b2015-08-28 04:07:10 -07001674 test::NullTransport transport;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001675 CreateSendConfig(1, 0, &transport);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001676 FrameObserver observer;
stefanff483612015-12-21 03:14:00 -08001677 video_send_config_.pre_encode_callback = &observer;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001678 CreateVideoStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001679
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001680 // Prepare five input frames. Send ordinary VideoFrame and texture frames
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001681 // alternatively.
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001682 std::vector<VideoFrame> input_frames;
perkjfa10b552016-10-02 23:45:26 -07001683 int width = 168;
1684 int height = 132;
1685
Peter Boströmeb66e802015-06-05 11:08:03 +02001686 test::FakeNativeHandle* handle1 = new test::FakeNativeHandle();
1687 test::FakeNativeHandle* handle2 = new test::FakeNativeHandle();
1688 test::FakeNativeHandle* handle3 = new test::FakeNativeHandle();
Peter Boström13f61df2016-01-04 22:36:38 +01001689 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001690 handle1, width, height, 1, 1, kVideoRotation_0));
Peter Boström13f61df2016-01-04 22:36:38 +01001691 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001692 handle2, width, height, 2, 2, kVideoRotation_0));
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001693 input_frames.push_back(CreateVideoFrame(width, height, 3));
1694 input_frames.push_back(CreateVideoFrame(width, height, 4));
Peter Boström13f61df2016-01-04 22:36:38 +01001695 input_frames.push_back(test::FakeNativeHandle::CreateFrame(
Peter Boströmeb66e802015-06-05 11:08:03 +02001696 handle3, width, height, 5, 5, kVideoRotation_0));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001697
stefanff483612015-12-21 03:14:00 -08001698 video_send_stream_->Start();
perkja49cbd32016-09-16 07:53:41 -07001699 test::FrameForwarder forwarder;
perkj803d97f2016-11-01 11:45:46 -07001700 video_send_stream_->SetSource(
1701 &forwarder, VideoSendStream::DegradationPreference::kBalanced);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001702 for (size_t i = 0; i < input_frames.size(); i++) {
perkja49cbd32016-09-16 07:53:41 -07001703 forwarder.IncomingCapturedFrame(input_frames[i]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001704 // Wait until the output frame is received before sending the next input
1705 // frame. Or the previous input frame may be replaced without delivering.
1706 observer.WaitOutputFrame();
1707 }
stefanff483612015-12-21 03:14:00 -08001708 video_send_stream_->Stop();
perkj803d97f2016-11-01 11:45:46 -07001709 video_send_stream_->SetSource(
1710 nullptr, VideoSendStream::DegradationPreference::kBalanced);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001711
1712 // Test if the input and output frames are the same. render_time_ms and
1713 // timestamp are not compared because capturer sets those values.
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001714 ExpectEqualFramesVector(input_frames, observer.output_frames());
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001715
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001716 DestroyStreams();
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001717}
1718
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001719void ExpectEqualFramesVector(const std::vector<VideoFrame>& frames1,
1720 const std::vector<VideoFrame>& frames2) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001721 EXPECT_EQ(frames1.size(), frames2.size());
1722 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
nisse26acec42016-04-15 03:43:39 -07001723 // Compare frame buffers, since we don't care about differing timestamps.
1724 EXPECT_TRUE(test::FrameBufsEqual(frames1[i].video_frame_buffer(),
1725 frames2[i].video_frame_buffer()));
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001726}
1727
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001728VideoFrame CreateVideoFrame(int width, int height, uint8_t data) {
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001729 const int kSizeY = width * height * 2;
kwiberg27f982b2016-03-01 11:52:33 -08001730 std::unique_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001731 memset(buffer.get(), data, kSizeY);
nissef0a7c5a2016-10-31 05:48:07 -07001732 VideoFrame frame(
1733 I420Buffer::Create(width, height, width, width / 2, width / 2),
1734 kVideoRotation_0, data);
magjed@webrtc.org2d2a30c2015-03-24 12:37:36 +00001735 frame.set_timestamp(data);
1736 frame.set_render_time_ms(data);
wuchengli@chromium.orgf425b552014-06-20 12:04:05 +00001737 return frame;
1738}
1739
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001740TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
1741 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
1742 public:
1743 EncoderStateObserver()
1744 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02001745 stream_(nullptr),
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001746 initialized_(false),
1747 callback_registered_(false),
1748 num_releases_(0),
1749 released_(false) {}
1750
1751 bool IsReleased() {
Peter Boströmf2f82832015-05-01 13:00:41 +02001752 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001753 return released_;
1754 }
1755
1756 bool IsReadyForEncode() {
Peter Boströmf2f82832015-05-01 13:00:41 +02001757 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001758 return initialized_ && callback_registered_;
1759 }
1760
1761 size_t num_releases() {
Peter Boströmf2f82832015-05-01 13:00:41 +02001762 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001763 return num_releases_;
1764 }
1765
1766 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001767 int32_t InitEncode(const VideoCodec* codecSettings,
1768 int32_t numberOfCores,
1769 size_t maxPayloadSize) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001770 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001771 EXPECT_FALSE(initialized_);
1772 initialized_ = true;
1773 released_ = false;
1774 return 0;
1775 }
1776
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001777 int32_t Encode(const VideoFrame& inputImage,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001778 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07001779 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001780 EXPECT_TRUE(IsReadyForEncode());
1781
Peter Boström5811a392015-12-10 13:02:50 +01001782 observation_complete_.Set();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001783 return 0;
1784 }
1785
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001786 int32_t RegisterEncodeCompleteCallback(
1787 EncodedImageCallback* callback) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001788 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001789 EXPECT_TRUE(initialized_);
1790 callback_registered_ = true;
1791 return 0;
1792 }
1793
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001794 int32_t Release() override {
Peter Boströmf2f82832015-05-01 13:00:41 +02001795 rtc::CritScope lock(&crit_);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001796 EXPECT_TRUE(IsReadyForEncode());
1797 EXPECT_FALSE(released_);
1798 initialized_ = false;
1799 callback_registered_ = false;
1800 released_ = true;
1801 ++num_releases_;
1802 return 0;
1803 }
1804
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001805 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001806 EXPECT_TRUE(IsReadyForEncode());
1807 return 0;
1808 }
1809
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001810 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001811 EXPECT_TRUE(IsReadyForEncode());
1812 return 0;
1813 }
1814
stefanff483612015-12-21 03:14:00 -08001815 void OnVideoStreamsCreated(
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001816 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001817 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001818 stream_ = send_stream;
1819 }
1820
stefanff483612015-12-21 03:14:00 -08001821 void ModifyVideoConfigs(
1822 VideoSendStream::Config* send_config,
1823 std::vector<VideoReceiveStream::Config>* receive_configs,
1824 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001825 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07001826 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001827 }
1828
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001829 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001830 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
Per21d45d22016-10-30 21:37:57 +01001831 EXPECT_EQ(0u, num_releases());
perkj26091b12016-09-01 01:17:40 -07001832 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
Per21d45d22016-10-30 21:37:57 +01001833 EXPECT_EQ(0u, num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001834 stream_->Stop();
1835 // Encoder should not be released before destroying the VideoSendStream.
1836 EXPECT_FALSE(IsReleased());
1837 EXPECT_TRUE(IsReadyForEncode());
1838 stream_->Start();
1839 // Sanity check, make sure we still encode frames with this encoder.
Peter Boström5811a392015-12-10 13:02:50 +01001840 EXPECT_TRUE(Wait()) << "Timed out while waiting for Encode.";
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001841 }
1842
Peter Boströmf2f82832015-05-01 13:00:41 +02001843 rtc::CriticalSection crit_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001844 VideoSendStream* stream_;
1845 bool initialized_ GUARDED_BY(crit_);
1846 bool callback_registered_ GUARDED_BY(crit_);
1847 size_t num_releases_ GUARDED_BY(crit_);
1848 bool released_ GUARDED_BY(crit_);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001849 VideoEncoderConfig encoder_config_;
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001850 } test_encoder;
1851
stefane74eef12016-01-08 06:47:13 -08001852 RunBaseTest(&test_encoder);
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001853
1854 EXPECT_TRUE(test_encoder.IsReleased());
Per21d45d22016-10-30 21:37:57 +01001855 EXPECT_EQ(1u, test_encoder.num_releases());
pbos@webrtc.org161f8082014-07-07 14:22:35 +00001856}
1857
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001858TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) {
1859 class VideoCodecConfigObserver : public test::SendTest,
1860 public test::FakeEncoder {
1861 public:
1862 VideoCodecConfigObserver()
1863 : SendTest(kDefaultTimeoutMs),
1864 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07001865 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02001866 num_initializations_(0),
1867 stream_(nullptr) {}
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001868
1869 private:
stefanff483612015-12-21 03:14:00 -08001870 void ModifyVideoConfigs(
1871 VideoSendStream::Config* send_config,
1872 std::vector<VideoReceiveStream::Config>* receive_configs,
1873 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001874 send_config->encoder_settings.encoder = this;
perkj26091b12016-09-01 01:17:40 -07001875 encoder_config_ = encoder_config->Copy();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001876 }
1877
stefanff483612015-12-21 03:14:00 -08001878 void OnVideoStreamsCreated(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001879 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001880 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001881 stream_ = send_stream;
1882 }
1883
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001884 int32_t InitEncode(const VideoCodec* config,
1885 int32_t number_of_cores,
1886 size_t max_payload_size) override {
Per21d45d22016-10-30 21:37:57 +01001887 if (num_initializations_ == 0) {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001888 // Verify default values.
1889 EXPECT_EQ(kRealtimeVideo, config->mode);
1890 } else {
1891 // Verify that changed values are propagated.
1892 EXPECT_EQ(kScreensharing, config->mode);
1893 }
1894 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01001895 init_encode_event_.Set();
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001896 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1897 }
1898
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001899 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07001900 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01001901 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001902
Erik Språng143cec12015-04-28 10:01:41 +02001903 encoder_config_.content_type = VideoEncoderConfig::ContentType::kScreen;
perkj26091b12016-09-01 01:17:40 -07001904 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07001905 EXPECT_TRUE(init_encode_event_.Wait(kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01001906 EXPECT_EQ(2u, num_initializations_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001907 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
1908 "new encoder settings.";
1909 }
1910
pbos14fe7082016-04-20 06:35:56 -07001911 rtc::Event init_encode_event_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001912 size_t num_initializations_;
1913 VideoSendStream* stream_;
1914 VideoEncoderConfig encoder_config_;
1915 } test;
1916
stefane74eef12016-01-08 06:47:13 -08001917 RunBaseTest(&test);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001918}
1919
Peter Boström53eda3d2015-03-27 15:53:18 +01001920static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4;
1921template <typename T>
1922class VideoCodecConfigObserver : public test::SendTest,
1923 public test::FakeEncoder {
Peter Boström53eda3d2015-03-27 15:53:18 +01001924 public:
1925 VideoCodecConfigObserver(VideoCodecType video_codec_type,
1926 const char* codec_name)
1927 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs),
1928 FakeEncoder(Clock::GetRealTimeClock()),
1929 video_codec_type_(video_codec_type),
1930 codec_name_(codec_name),
pbos14fe7082016-04-20 06:35:56 -07001931 init_encode_event_(false, false),
Erik Språng737336d2016-07-29 12:59:36 +02001932 num_initializations_(0),
1933 stream_(nullptr) {
Peter Boström53eda3d2015-03-27 15:53:18 +01001934 memset(&encoder_settings_, 0, sizeof(encoder_settings_));
1935 }
1936
1937 private:
perkjfa10b552016-10-02 23:45:26 -07001938 class VideoStreamFactory
1939 : public VideoEncoderConfig::VideoStreamFactoryInterface {
1940 public:
1941 VideoStreamFactory() {}
1942
1943 private:
1944 std::vector<VideoStream> CreateEncoderStreams(
1945 int width,
1946 int height,
1947 const VideoEncoderConfig& encoder_config) override {
1948 std::vector<VideoStream> streams =
1949 test::CreateVideoStreams(width, height, encoder_config);
1950 for (size_t i = 0; i < streams.size(); ++i) {
1951 streams[i].temporal_layer_thresholds_bps.resize(
1952 kVideoCodecConfigObserverNumberOfTemporalLayers - 1);
1953 }
1954 return streams;
1955 }
1956 };
1957
stefanff483612015-12-21 03:14:00 -08001958 void ModifyVideoConfigs(
1959 VideoSendStream::Config* send_config,
1960 std::vector<VideoReceiveStream::Config>* receive_configs,
1961 VideoEncoderConfig* encoder_config) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01001962 send_config->encoder_settings.encoder = this;
1963 send_config->encoder_settings.payload_name = codec_name_;
1964
kthelgason29a44e32016-09-27 03:52:02 -07001965 encoder_config->encoder_specific_settings = GetEncoderSpecificSettings();
perkjfa10b552016-10-02 23:45:26 -07001966 encoder_config->video_stream_factory =
1967 new rtc::RefCountedObject<VideoStreamFactory>();
perkj26091b12016-09-01 01:17:40 -07001968 encoder_config_ = encoder_config->Copy();
Peter Boström53eda3d2015-03-27 15:53:18 +01001969 }
1970
stefanff483612015-12-21 03:14:00 -08001971 void OnVideoStreamsCreated(
Peter Boström53eda3d2015-03-27 15:53:18 +01001972 VideoSendStream* send_stream,
1973 const std::vector<VideoReceiveStream*>& receive_streams) override {
1974 stream_ = send_stream;
1975 }
1976
1977 int32_t InitEncode(const VideoCodec* config,
1978 int32_t number_of_cores,
1979 size_t max_payload_size) override {
1980 EXPECT_EQ(video_codec_type_, config->codecType);
1981 VerifyCodecSpecifics(*config);
1982 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01001983 init_encode_event_.Set();
Peter Boström53eda3d2015-03-27 15:53:18 +01001984 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1985 }
1986
1987 void VerifyCodecSpecifics(const VideoCodec& config) const;
kthelgason29a44e32016-09-27 03:52:02 -07001988 rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
1989 GetEncoderSpecificSettings() const;
Peter Boström53eda3d2015-03-27 15:53:18 +01001990
1991 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07001992 EXPECT_TRUE(
1993 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01001994 ASSERT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
Peter Boström53eda3d2015-03-27 15:53:18 +01001995
1996 encoder_settings_.frameDroppingOn = true;
kthelgason29a44e32016-09-27 03:52:02 -07001997 encoder_config_.encoder_specific_settings = GetEncoderSpecificSettings();
perkj26091b12016-09-01 01:17:40 -07001998 stream_->ReconfigureVideoEncoder(std::move(encoder_config_));
pbos14fe7082016-04-20 06:35:56 -07001999 ASSERT_TRUE(
2000 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002001 EXPECT_EQ(2u, num_initializations_)
Peter Boström53eda3d2015-03-27 15:53:18 +01002002 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
2003 "new encoder settings.";
2004 }
2005
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002006 int32_t Encode(const VideoFrame& input_image,
Peter Boström53eda3d2015-03-27 15:53:18 +01002007 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07002008 const std::vector<FrameType>* frame_types) override {
Peter Boström53eda3d2015-03-27 15:53:18 +01002009 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
2010 return 0;
2011 }
2012
2013 T encoder_settings_;
2014 const VideoCodecType video_codec_type_;
2015 const char* const codec_name_;
pbos14fe7082016-04-20 06:35:56 -07002016 rtc::Event init_encode_event_;
Peter Boström53eda3d2015-03-27 15:53:18 +01002017 size_t num_initializations_;
2018 VideoSendStream* stream_;
2019 VideoEncoderConfig encoder_config_;
2020};
2021
2022template <>
2023void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics(
2024 const VideoCodec& config) const {
hta257dc392016-10-25 09:05:06 -07002025 EXPECT_EQ(
2026 0, memcmp(&config.H264(), &encoder_settings_, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002027}
kthelgason29a44e32016-09-27 03:52:02 -07002028
2029template <>
2030rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2031VideoCodecConfigObserver<VideoCodecH264>::GetEncoderSpecificSettings() const {
2032 return new rtc::RefCountedObject<
2033 VideoEncoderConfig::H264EncoderSpecificSettings>(encoder_settings_);
2034}
2035
Peter Boström53eda3d2015-03-27 15:53:18 +01002036template <>
2037void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics(
2038 const VideoCodec& config) const {
2039 // Check that the number of temporal layers has propagated properly to
2040 // VideoCodec.
2041 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002042 config.VP8().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002043
2044 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2045 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2046 config.simulcastStream[i].numberOfTemporalLayers);
2047 }
2048
2049 // Set expected temporal layers as they should have been set when
2050 // reconfiguring the encoder and not match the set config.
2051 VideoCodecVP8 encoder_settings = encoder_settings_;
2052 encoder_settings.numberOfTemporalLayers =
2053 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002054 EXPECT_EQ(
2055 0, memcmp(&config.VP8(), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002056}
kthelgason29a44e32016-09-27 03:52:02 -07002057
2058template <>
2059rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2060VideoCodecConfigObserver<VideoCodecVP8>::GetEncoderSpecificSettings() const {
2061 return new rtc::RefCountedObject<
2062 VideoEncoderConfig::Vp8EncoderSpecificSettings>(encoder_settings_);
2063}
2064
Peter Boström53eda3d2015-03-27 15:53:18 +01002065template <>
2066void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics(
2067 const VideoCodec& config) const {
2068 // Check that the number of temporal layers has propagated properly to
2069 // VideoCodec.
2070 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
hta257dc392016-10-25 09:05:06 -07002071 config.VP9().numberOfTemporalLayers);
Peter Boström53eda3d2015-03-27 15:53:18 +01002072
2073 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) {
2074 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers,
2075 config.simulcastStream[i].numberOfTemporalLayers);
2076 }
2077
2078 // Set expected temporal layers as they should have been set when
2079 // reconfiguring the encoder and not match the set config.
2080 VideoCodecVP9 encoder_settings = encoder_settings_;
2081 encoder_settings.numberOfTemporalLayers =
2082 kVideoCodecConfigObserverNumberOfTemporalLayers;
hta257dc392016-10-25 09:05:06 -07002083 EXPECT_EQ(
2084 0, memcmp(&(config.VP9()), &encoder_settings, sizeof(encoder_settings_)));
Peter Boström53eda3d2015-03-27 15:53:18 +01002085}
2086
kthelgason29a44e32016-09-27 03:52:02 -07002087template <>
2088rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
2089VideoCodecConfigObserver<VideoCodecVP9>::GetEncoderSpecificSettings() const {
2090 return new rtc::RefCountedObject<
2091 VideoEncoderConfig::Vp9EncoderSpecificSettings>(encoder_settings_);
2092}
2093
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002094TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
Peter Boström53eda3d2015-03-27 15:53:18 +01002095 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8");
stefane74eef12016-01-08 06:47:13 -08002096 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002097}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002098
Peter Boström53eda3d2015-03-27 15:53:18 +01002099TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) {
2100 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9");
stefane74eef12016-01-08 06:47:13 -08002101 RunBaseTest(&test);
Peter Boström53eda3d2015-03-27 15:53:18 +01002102}
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002103
Peter Boström53eda3d2015-03-27 15:53:18 +01002104TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) {
2105 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264");
stefane74eef12016-01-08 06:47:13 -08002106 RunBaseTest(&test);
pbos@webrtc.org91f17522014-07-10 10:13:37 +00002107}
2108
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002109TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002110 class RtcpSenderReportTest : public test::SendTest {
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002111 public:
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002112 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs),
2113 rtp_packets_sent_(0),
2114 media_bytes_sent_(0) {}
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002115
2116 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002117 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002118 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002119 RTPHeader header;
2120 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002121 ++rtp_packets_sent_;
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002122 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
2123 return SEND_PACKET;
2124 }
2125
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002126 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan4b569042015-11-11 06:39:57 -08002127 rtc::CritScope lock(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002128 RTCPUtility::RTCPParserV2 parser(packet, length, true);
2129 EXPECT_TRUE(parser.IsValid());
2130
2131 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
Erik Språng242e22b2015-05-11 10:17:43 +02002132 while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) {
2133 if (packet_type == RTCPUtility::RTCPPacketTypes::kSr) {
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002134 // Only compare sent media bytes if SenderPacketCount matches the
2135 // number of sent rtp packets (a new rtp packet could be sent before
2136 // the rtcp packet).
2137 if (parser.Packet().SR.SenderOctetCount > 0 &&
2138 parser.Packet().SR.SenderPacketCount == rtp_packets_sent_) {
2139 EXPECT_EQ(media_bytes_sent_, parser.Packet().SR.SenderOctetCount);
Peter Boström5811a392015-12-10 13:02:50 +01002140 observation_complete_.Set();
asapersson@webrtc.org14674212015-02-23 08:14:07 +00002141 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002142 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002143 packet_type = parser.Iterate();
2144 }
2145
2146 return SEND_PACKET;
2147 }
2148
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002149 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002150 EXPECT_TRUE(Wait()) << "Timed out while waiting for RTCP sender report.";
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002151 }
2152
stefan4b569042015-11-11 06:39:57 -08002153 rtc::CriticalSection crit_;
2154 size_t rtp_packets_sent_ GUARDED_BY(&crit_);
2155 size_t media_bytes_sent_ GUARDED_BY(&crit_);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002156 } test;
2157
stefane74eef12016-01-08 06:47:13 -08002158 RunBaseTest(&test);
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +00002159}
2160
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002161TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) {
2162 static const int kScreencastTargetBitrateKbps = 200;
perkjfa10b552016-10-02 23:45:26 -07002163
2164 class VideoStreamFactory
2165 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2166 public:
2167 VideoStreamFactory() {}
2168
2169 private:
2170 std::vector<VideoStream> CreateEncoderStreams(
2171 int width,
2172 int height,
2173 const VideoEncoderConfig& encoder_config) override {
2174 std::vector<VideoStream> streams =
2175 test::CreateVideoStreams(width, height, encoder_config);
2176 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
2177 streams[0].temporal_layer_thresholds_bps.push_back(
2178 kScreencastTargetBitrateKbps * 1000);
2179 return streams;
2180 }
2181 };
2182
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002183 class ScreencastTargetBitrateTest : public test::SendTest,
2184 public test::FakeEncoder {
2185 public:
2186 ScreencastTargetBitrateTest()
2187 : SendTest(kDefaultTimeoutMs),
2188 test::FakeEncoder(Clock::GetRealTimeClock()) {}
2189
2190 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002191 int32_t InitEncode(const VideoCodec* config,
2192 int32_t number_of_cores,
2193 size_t max_payload_size) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002194 EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps),
2195 config->targetBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002196 observation_complete_.Set();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002197 return test::FakeEncoder::InitEncode(
2198 config, number_of_cores, max_payload_size);
2199 }
stefanff483612015-12-21 03:14:00 -08002200 void ModifyVideoConfigs(
2201 VideoSendStream::Config* send_config,
2202 std::vector<VideoReceiveStream::Config>* receive_configs,
2203 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002204 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002205 EXPECT_EQ(1u, encoder_config->number_of_streams);
2206 encoder_config->video_stream_factory =
2207 new rtc::RefCountedObject<VideoStreamFactory>();
Erik Språng143cec12015-04-28 10:01:41 +02002208 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002209 }
2210
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002211 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002212 EXPECT_TRUE(Wait())
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002213 << "Timed out while waiting for the encoder to be initialized.";
2214 }
2215 } test;
2216
stefane74eef12016-01-08 06:47:13 -08002217 RunBaseTest(&test);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002218}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002219
philipelc6957c72016-04-28 15:52:49 +02002220TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002221 // These are chosen to be "kind of odd" to not be accidentally checked against
2222 // default values.
2223 static const int kMinBitrateKbps = 137;
2224 static const int kStartBitrateKbps = 345;
2225 static const int kLowerMaxBitrateKbps = 312;
2226 static const int kMaxBitrateKbps = 413;
2227 static const int kIncreasedStartBitrateKbps = 451;
2228 static const int kIncreasedMaxBitrateKbps = 597;
2229 class EncoderBitrateThresholdObserver : public test::SendTest,
2230 public test::FakeEncoder {
2231 public:
2232 EncoderBitrateThresholdObserver()
2233 : SendTest(kDefaultTimeoutMs),
2234 FakeEncoder(Clock::GetRealTimeClock()),
pbos14fe7082016-04-20 06:35:56 -07002235 init_encode_event_(false, false),
perkj26091b12016-09-01 01:17:40 -07002236 bitrate_changed_event_(false, false),
2237 target_bitrate_(0),
Erik Språng737336d2016-07-29 12:59:36 +02002238 num_initializations_(0),
2239 call_(nullptr),
2240 send_stream_(nullptr) {}
pbos@webrtc.org00873182014-11-25 14:03:34 +00002241
2242 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002243 int32_t InitEncode(const VideoCodec* codecSettings,
2244 int32_t numberOfCores,
2245 size_t maxPayloadSize) override {
perkj26091b12016-09-01 01:17:40 -07002246 EXPECT_GE(codecSettings->startBitrate, codecSettings->minBitrate);
2247 EXPECT_LE(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002248 if (num_initializations_ == 0) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002249 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps),
2250 codecSettings->minBitrate);
2251 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps),
2252 codecSettings->startBitrate);
2253 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps),
2254 codecSettings->maxBitrate);
Peter Boström5811a392015-12-10 13:02:50 +01002255 observation_complete_.Set();
Per21d45d22016-10-30 21:37:57 +01002256 } else if (num_initializations_ == 1) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002257 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps),
2258 codecSettings->maxBitrate);
2259 // The start bitrate should be kept (-1) and capped to the max bitrate.
2260 // Since this is not an end-to-end call no receiver should have been
2261 // returning a REMB that could lower this estimate.
2262 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate);
Per21d45d22016-10-30 21:37:57 +01002263 } else if (num_initializations_ == 2) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002264 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps),
2265 codecSettings->maxBitrate);
perkj26091b12016-09-01 01:17:40 -07002266 // The start bitrate will be whatever the rate BitRateController
2267 // has currently configured but in the span of the set max and min
2268 // bitrate.
pbos@webrtc.org00873182014-11-25 14:03:34 +00002269 }
2270 ++num_initializations_;
Per21d45d22016-10-30 21:37:57 +01002271 init_encode_event_.Set();
2272
pbos@webrtc.org00873182014-11-25 14:03:34 +00002273 return FakeEncoder::InitEncode(codecSettings, numberOfCores,
2274 maxPayloadSize);
2275 }
2276
perkj26091b12016-09-01 01:17:40 -07002277 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override {
2278 {
2279 rtc::CritScope lock(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002280 if (target_bitrate_ == newBitRate) {
2281 return FakeEncoder::SetRates(newBitRate, frameRate);
2282 }
perkj26091b12016-09-01 01:17:40 -07002283 target_bitrate_ = newBitRate;
2284 }
2285 bitrate_changed_event_.Set();
2286 return FakeEncoder::SetRates(newBitRate, frameRate);
2287 }
2288
2289 void WaitForSetRates(uint32_t expected_bitrate) {
2290 EXPECT_TRUE(
2291 bitrate_changed_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
2292 << "Timed out while waiting encoder rate to be set.";
2293 rtc::CritScope lock(&crit_);
2294 EXPECT_EQ(expected_bitrate, target_bitrate_);
2295 }
2296
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002297 Call::Config GetSenderCallConfig() override {
skvlad11a9cbf2016-10-07 11:53:05 -07002298 Call::Config config(&event_log_);
Stefan Holmere5904162015-03-26 11:11:06 +01002299 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000;
2300 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000;
2301 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002302 return config;
2303 }
2304
perkjfa10b552016-10-02 23:45:26 -07002305 class VideoStreamFactory
2306 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2307 public:
2308 explicit VideoStreamFactory(int min_bitrate_bps)
2309 : min_bitrate_bps_(min_bitrate_bps) {}
2310
2311 private:
2312 std::vector<VideoStream> CreateEncoderStreams(
2313 int width,
2314 int height,
2315 const VideoEncoderConfig& encoder_config) override {
2316 std::vector<VideoStream> streams =
2317 test::CreateVideoStreams(width, height, encoder_config);
2318 streams[0].min_bitrate_bps = min_bitrate_bps_;
2319 return streams;
2320 }
2321
2322 const int min_bitrate_bps_;
2323 };
2324
stefanff483612015-12-21 03:14:00 -08002325 void ModifyVideoConfigs(
2326 VideoSendStream::Config* send_config,
2327 std::vector<VideoReceiveStream::Config>* receive_configs,
2328 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002329 send_config->encoder_settings.encoder = this;
2330 // Set bitrates lower/higher than min/max to make sure they are properly
2331 // capped.
perkjfa10b552016-10-02 23:45:26 -07002332 encoder_config->max_bitrate_bps = kMaxBitrateKbps * 1000;
2333 // Create a new StreamFactory to be able to set
2334 // |VideoStream.min_bitrate_bps|.
2335 encoder_config->video_stream_factory =
2336 new rtc::RefCountedObject<VideoStreamFactory>(kMinBitrateKbps * 1000);
perkj26091b12016-09-01 01:17:40 -07002337 encoder_config_ = encoder_config->Copy();
pbos@webrtc.org00873182014-11-25 14:03:34 +00002338 }
2339
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002340 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002341 call_ = sender_call;
2342 }
2343
stefanff483612015-12-21 03:14:00 -08002344 void OnVideoStreamsCreated(
Stefan Holmere5904162015-03-26 11:11:06 +01002345 VideoSendStream* send_stream,
2346 const std::vector<VideoReceiveStream*>& receive_streams) override {
2347 send_stream_ = send_stream;
2348 }
2349
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002350 void PerformTest() override {
pbos14fe7082016-04-20 06:35:56 -07002351 ASSERT_TRUE(
2352 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs))
perkj26091b12016-09-01 01:17:40 -07002353 << "Timed out while waiting for encoder to be configured.";
2354 WaitForSetRates(kStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002355 Call::Config::BitrateConfig bitrate_config;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002356 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000;
2357 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2358 call_->SetBitrateConfig(bitrate_config);
perkj26091b12016-09-01 01:17:40 -07002359 // Encoder rate is capped by EncoderConfig max_bitrate_bps.
2360 WaitForSetRates(kMaxBitrateKbps);
perkjfa10b552016-10-02 23:45:26 -07002361 encoder_config_.max_bitrate_bps = kLowerMaxBitrateKbps * 1000;
perkj26091b12016-09-01 01:17:40 -07002362 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
pbos14fe7082016-04-20 06:35:56 -07002363 ASSERT_TRUE(
2364 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002365 EXPECT_EQ(2, num_initializations_)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002366 << "Encoder should have been reconfigured with the new value.";
perkjfa10b552016-10-02 23:45:26 -07002367 WaitForSetRates(kLowerMaxBitrateKbps);
2368
2369 encoder_config_.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000;
2370 send_stream_->ReconfigureVideoEncoder(encoder_config_.Copy());
2371 ASSERT_TRUE(
2372 init_encode_event_.Wait(VideoSendStreamTest::kDefaultTimeoutMs));
Per21d45d22016-10-30 21:37:57 +01002373 EXPECT_EQ(3, num_initializations_)
perkjfa10b552016-10-02 23:45:26 -07002374 << "Encoder should have been reconfigured with the new value.";
perkj26091b12016-09-01 01:17:40 -07002375 // Expected target bitrate is the start bitrate set in the call to
2376 // call_->SetBitrateConfig.
2377 WaitForSetRates(kIncreasedStartBitrateKbps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002378 }
2379
pbos14fe7082016-04-20 06:35:56 -07002380 rtc::Event init_encode_event_;
perkj26091b12016-09-01 01:17:40 -07002381 rtc::Event bitrate_changed_event_;
2382 rtc::CriticalSection crit_;
2383 uint32_t target_bitrate_ GUARDED_BY(&crit_);
perkjfa10b552016-10-02 23:45:26 -07002384
pbos@webrtc.org00873182014-11-25 14:03:34 +00002385 int num_initializations_;
2386 webrtc::Call* call_;
Stefan Holmere5904162015-03-26 11:11:06 +01002387 webrtc::VideoSendStream* send_stream_;
2388 webrtc::VideoEncoderConfig encoder_config_;
pbos@webrtc.org00873182014-11-25 14:03:34 +00002389 } test;
2390
stefane74eef12016-01-08 06:47:13 -08002391 RunBaseTest(&test);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002392}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002393
2394TEST_F(VideoSendStreamTest, ReportsSentResolution) {
2395 static const size_t kNumStreams = 3;
2396 // Unusual resolutions to make sure that they are the ones being reported.
2397 static const struct {
2398 int width;
2399 int height;
2400 } kEncodedResolution[kNumStreams] = {
2401 {241, 181}, {300, 121}, {121, 221}};
2402 class ScreencastTargetBitrateTest : public test::SendTest,
2403 public test::FakeEncoder {
2404 public:
2405 ScreencastTargetBitrateTest()
2406 : SendTest(kDefaultTimeoutMs),
Erik Språng737336d2016-07-29 12:59:36 +02002407 test::FakeEncoder(Clock::GetRealTimeClock()),
2408 send_stream_(nullptr) {}
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002409
2410 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002411 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002412 const CodecSpecificInfo* codecSpecificInfo,
pbos22993e12015-10-19 02:39:06 -07002413 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002414 CodecSpecificInfo specifics;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002415 specifics.codecType = kVideoCodecGeneric;
2416
2417 uint8_t buffer[16] = {0};
2418 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer));
2419 encoded._timeStamp = input_image.timestamp();
2420 encoded.capture_time_ms_ = input_image.render_time_ms();
2421
2422 for (size_t i = 0; i < kNumStreams; ++i) {
2423 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i);
2424 encoded._frameType = (*frame_types)[i];
2425 encoded._encodedWidth = kEncodedResolution[i].width;
2426 encoded._encodedHeight = kEncodedResolution[i].height;
Peter Boström74f6e9e2016-04-04 17:56:10 +02002427 RTC_DCHECK(callback_);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00002428 if (callback_->Encoded(encoded, &specifics, nullptr) != 0)
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002429 return -1;
2430 }
2431
Peter Boström5811a392015-12-10 13:02:50 +01002432 observation_complete_.Set();
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002433 return 0;
2434 }
stefanff483612015-12-21 03:14:00 -08002435 void ModifyVideoConfigs(
2436 VideoSendStream::Config* send_config,
2437 std::vector<VideoReceiveStream::Config>* receive_configs,
2438 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002439 send_config->encoder_settings.encoder = this;
perkjfa10b552016-10-02 23:45:26 -07002440 EXPECT_EQ(kNumStreams, encoder_config->number_of_streams);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002441 }
2442
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002443 size_t GetNumVideoStreams() const override { return kNumStreams; }
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002444
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002445 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002446 EXPECT_TRUE(Wait())
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002447 << "Timed out while waiting for the encoder to send one frame.";
2448 VideoSendStream::Stats stats = send_stream_->GetStats();
2449
2450 for (size_t i = 0; i < kNumStreams; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002451 ASSERT_TRUE(stats.substreams.find(kVideoSendSsrcs[i]) !=
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002452 stats.substreams.end())
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002453 << "No stats for SSRC: " << kVideoSendSsrcs[i]
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002454 << ", stats should exist as soon as frames have been encoded.";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002455 VideoSendStream::StreamStats ssrc_stats =
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002456 stats.substreams[kVideoSendSsrcs[i]];
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002457 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
2458 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002459 }
2460 }
2461
stefanff483612015-12-21 03:14:00 -08002462 void OnVideoStreamsCreated(
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002463 VideoSendStream* send_stream,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002464 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002465 send_stream_ = send_stream;
2466 }
2467
2468 VideoSendStream* send_stream_;
2469 } test;
2470
stefane74eef12016-01-08 06:47:13 -08002471 RunBaseTest(&test);
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002472}
philipel0f9af012015-09-01 07:01:51 -07002473
Peter Boström12996152016-05-14 02:03:18 +02002474#if !defined(RTC_DISABLE_VP9)
Åsa Perssonff24c042015-12-04 10:58:08 +01002475class Vp9HeaderObserver : public test::SendTest {
philipel0f9af012015-09-01 07:01:51 -07002476 public:
Åsa Perssonff24c042015-12-04 10:58:08 +01002477 Vp9HeaderObserver()
2478 : SendTest(VideoSendStreamTest::kLongTimeoutMs),
philipel7fabd462015-09-03 04:42:32 -07002479 vp9_encoder_(VP9Encoder::Create()),
Åsa Perssonff24c042015-12-04 10:58:08 +01002480 vp9_settings_(VideoEncoder::GetDefaultVp9Settings()),
2481 packets_sent_(0),
perkjfa10b552016-10-02 23:45:26 -07002482 frames_sent_(0),
2483 expected_width_(0),
2484 expected_height_(0) {}
philipel7fabd462015-09-03 04:42:32 -07002485
stefanff483612015-12-21 03:14:00 -08002486 virtual void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07002487 VideoSendStream::Config* send_config,
2488 std::vector<VideoReceiveStream::Config>* receive_configs,
2489 VideoEncoderConfig* encoder_config) {}
2490
Åsa Perssonff24c042015-12-04 10:58:08 +01002491 virtual void InspectHeader(const RTPVideoHeaderVP9& vp9) = 0;
philipel0f9af012015-09-01 07:01:51 -07002492
2493 private:
2494 const int kVp9PayloadType = 105;
2495
perkjfa10b552016-10-02 23:45:26 -07002496 class VideoStreamFactory
2497 : public VideoEncoderConfig::VideoStreamFactoryInterface {
2498 public:
2499 explicit VideoStreamFactory(size_t number_of_temporal_layers)
2500 : number_of_temporal_layers_(number_of_temporal_layers) {}
2501
2502 private:
2503 std::vector<VideoStream> CreateEncoderStreams(
2504 int width,
2505 int height,
2506 const VideoEncoderConfig& encoder_config) override {
2507 std::vector<VideoStream> streams =
2508 test::CreateVideoStreams(width, height, encoder_config);
2509 streams[0].temporal_layer_thresholds_bps.resize(
2510 number_of_temporal_layers_ - 1);
2511 return streams;
2512 }
2513
2514 const size_t number_of_temporal_layers_;
2515 };
2516
stefanff483612015-12-21 03:14:00 -08002517 void ModifyVideoConfigs(
2518 VideoSendStream::Config* send_config,
2519 std::vector<VideoReceiveStream::Config>* receive_configs,
2520 VideoEncoderConfig* encoder_config) override {
philipel7fabd462015-09-03 04:42:32 -07002521 send_config->encoder_settings.encoder = vp9_encoder_.get();
philipel0f9af012015-09-01 07:01:51 -07002522 send_config->encoder_settings.payload_name = "VP9";
2523 send_config->encoder_settings.payload_type = kVp9PayloadType;
stefanff483612015-12-21 03:14:00 -08002524 ModifyVideoConfigsHook(send_config, receive_configs, encoder_config);
kthelgason29a44e32016-09-27 03:52:02 -07002525 encoder_config->encoder_specific_settings = new rtc::RefCountedObject<
2526 VideoEncoderConfig::Vp9EncoderSpecificSettings>(vp9_settings_);
perkjfa10b552016-10-02 23:45:26 -07002527 EXPECT_EQ(1u, encoder_config->number_of_streams);
2528 encoder_config->video_stream_factory =
2529 new rtc::RefCountedObject<VideoStreamFactory>(
2530 vp9_settings_.numberOfTemporalLayers);
perkj26091b12016-09-01 01:17:40 -07002531 encoder_config_ = encoder_config->Copy();
philipel0f9af012015-09-01 07:01:51 -07002532 }
2533
perkjfa10b552016-10-02 23:45:26 -07002534 void ModifyVideoCaptureStartResolution(int* width,
2535 int* height,
2536 int* frame_rate) override {
2537 expected_width_ = *width;
2538 expected_height_ = *height;
2539 }
2540
philipel0f9af012015-09-01 07:01:51 -07002541 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002542 EXPECT_TRUE(Wait()) << "Test timed out waiting for VP9 packet, num frames "
2543 << frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002544 }
2545
2546 Action OnSendRtp(const uint8_t* packet, size_t length) override {
2547 RTPHeader header;
2548 EXPECT_TRUE(parser_->Parse(packet, length, &header));
2549
Åsa Perssonff24c042015-12-04 10:58:08 +01002550 EXPECT_EQ(kVp9PayloadType, header.payloadType);
2551 const uint8_t* payload = packet + header.headerLength;
2552 size_t payload_length = length - header.headerLength - header.paddingLength;
philipel0f9af012015-09-01 07:01:51 -07002553
Åsa Perssonff24c042015-12-04 10:58:08 +01002554 bool new_packet = packets_sent_ == 0 ||
2555 IsNewerSequenceNumber(header.sequenceNumber,
2556 last_header_.sequenceNumber);
2557 if (payload_length > 0 && new_packet) {
2558 RtpDepacketizer::ParsedPayload parsed;
2559 RtpDepacketizerVp9 depacketizer;
2560 EXPECT_TRUE(depacketizer.Parse(&parsed, payload, payload_length));
2561 EXPECT_EQ(RtpVideoCodecTypes::kRtpVideoVp9, parsed.type.Video.codec);
2562 // Verify common fields for all configurations.
2563 VerifyCommonHeader(parsed.type.Video.codecHeader.VP9);
2564 CompareConsecutiveFrames(header, parsed.type.Video);
2565 // Verify configuration specific settings.
2566 InspectHeader(parsed.type.Video.codecHeader.VP9);
philipel0f9af012015-09-01 07:01:51 -07002567
Åsa Perssonff24c042015-12-04 10:58:08 +01002568 ++packets_sent_;
2569 if (header.markerBit) {
2570 ++frames_sent_;
philipel0f9af012015-09-01 07:01:51 -07002571 }
Åsa Perssonff24c042015-12-04 10:58:08 +01002572 last_header_ = header;
2573 last_vp9_ = parsed.type.Video.codecHeader.VP9;
philipel0f9af012015-09-01 07:01:51 -07002574 }
philipel0f9af012015-09-01 07:01:51 -07002575 return SEND_PACKET;
2576 }
2577
philipel7fabd462015-09-03 04:42:32 -07002578 protected:
Åsa Perssonff24c042015-12-04 10:58:08 +01002579 bool ContinuousPictureId(const RTPVideoHeaderVP9& vp9) const {
2580 if (last_vp9_.picture_id > vp9.picture_id) {
2581 return vp9.picture_id == 0; // Wrap.
2582 } else {
2583 return vp9.picture_id == last_vp9_.picture_id + 1;
2584 }
2585 }
2586
2587 void VerifySpatialIdxWithinFrame(const RTPVideoHeaderVP9& vp9) const {
Åsa Perssonff24c042015-12-04 10:58:08 +01002588 bool new_layer = vp9.spatial_idx != last_vp9_.spatial_idx;
2589 EXPECT_EQ(new_layer, vp9.beginning_of_frame);
2590 EXPECT_EQ(new_layer, last_vp9_.end_of_frame);
2591 EXPECT_EQ(new_layer ? last_vp9_.spatial_idx + 1 : last_vp9_.spatial_idx,
2592 vp9.spatial_idx);
2593 }
2594
2595 void VerifyFixedTemporalLayerStructure(const RTPVideoHeaderVP9& vp9,
2596 uint8_t num_layers) const {
2597 switch (num_layers) {
2598 case 0:
2599 VerifyTemporalLayerStructure0(vp9);
2600 break;
2601 case 1:
2602 VerifyTemporalLayerStructure1(vp9);
2603 break;
2604 case 2:
2605 VerifyTemporalLayerStructure2(vp9);
2606 break;
2607 case 3:
2608 VerifyTemporalLayerStructure3(vp9);
2609 break;
2610 default:
2611 RTC_NOTREACHED();
2612 }
2613 }
2614
2615 void VerifyTemporalLayerStructure0(const RTPVideoHeaderVP9& vp9) const {
2616 EXPECT_EQ(kNoTl0PicIdx, vp9.tl0_pic_idx);
2617 EXPECT_EQ(kNoTemporalIdx, vp9.temporal_idx); // no tid
2618 EXPECT_FALSE(vp9.temporal_up_switch);
2619 }
2620
2621 void VerifyTemporalLayerStructure1(const RTPVideoHeaderVP9& vp9) const {
2622 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2623 EXPECT_EQ(0, vp9.temporal_idx); // 0,0,0,...
2624 EXPECT_FALSE(vp9.temporal_up_switch);
2625 }
2626
2627 void VerifyTemporalLayerStructure2(const RTPVideoHeaderVP9& vp9) const {
2628 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2629 EXPECT_GE(vp9.temporal_idx, 0); // 0,1,0,1,... (tid reset on I-frames).
2630 EXPECT_LE(vp9.temporal_idx, 1);
2631 EXPECT_EQ(vp9.temporal_idx > 0, vp9.temporal_up_switch);
2632 if (IsNewPictureId(vp9)) {
2633 uint8_t expected_tid =
2634 (!vp9.inter_pic_predicted || last_vp9_.temporal_idx == 1) ? 0 : 1;
2635 EXPECT_EQ(expected_tid, vp9.temporal_idx);
2636 }
2637 }
2638
2639 void VerifyTemporalLayerStructure3(const RTPVideoHeaderVP9& vp9) const {
2640 EXPECT_NE(kNoTl0PicIdx, vp9.tl0_pic_idx);
2641 EXPECT_GE(vp9.temporal_idx, 0); // 0,2,1,2,... (tid reset on I-frames).
2642 EXPECT_LE(vp9.temporal_idx, 2);
2643 if (IsNewPictureId(vp9) && vp9.inter_pic_predicted) {
2644 EXPECT_NE(vp9.temporal_idx, last_vp9_.temporal_idx);
2645 switch (vp9.temporal_idx) {
2646 case 0:
2647 EXPECT_EQ(2, last_vp9_.temporal_idx);
2648 EXPECT_FALSE(vp9.temporal_up_switch);
2649 break;
2650 case 1:
2651 EXPECT_EQ(2, last_vp9_.temporal_idx);
2652 EXPECT_TRUE(vp9.temporal_up_switch);
2653 break;
2654 case 2:
2655 EXPECT_EQ(last_vp9_.temporal_idx == 0, vp9.temporal_up_switch);
2656 break;
2657 }
2658 }
2659 }
2660
2661 void VerifyTl0Idx(const RTPVideoHeaderVP9& vp9) const {
2662 if (vp9.tl0_pic_idx == kNoTl0PicIdx)
2663 return;
2664
2665 uint8_t expected_tl0_idx = last_vp9_.tl0_pic_idx;
2666 if (vp9.temporal_idx == 0)
2667 ++expected_tl0_idx;
2668 EXPECT_EQ(expected_tl0_idx, vp9.tl0_pic_idx);
2669 }
2670
2671 bool IsNewPictureId(const RTPVideoHeaderVP9& vp9) const {
2672 return frames_sent_ > 0 && (vp9.picture_id != last_vp9_.picture_id);
2673 }
2674
2675 // Flexible mode (F=1): Non-flexible mode (F=0):
2676 //
2677 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2678 // |I|P|L|F|B|E|V|-| |I|P|L|F|B|E|V|-|
2679 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2680 // I: |M| PICTURE ID | I: |M| PICTURE ID |
2681 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2682 // M: | EXTENDED PID | M: | EXTENDED PID |
2683 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2684 // L: | T |U| S |D| L: | T |U| S |D|
2685 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2686 // P,F: | P_DIFF |X|N| | TL0PICIDX |
2687 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2688 // X: |EXTENDED P_DIFF| V: | SS .. |
2689 // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
2690 // V: | SS .. |
2691 // +-+-+-+-+-+-+-+-+
2692 void VerifyCommonHeader(const RTPVideoHeaderVP9& vp9) const {
2693 EXPECT_EQ(kMaxTwoBytePictureId, vp9.max_picture_id); // M:1
2694 EXPECT_NE(kNoPictureId, vp9.picture_id); // I:1
2695 EXPECT_EQ(vp9_settings_.flexibleMode, vp9.flexible_mode); // F
2696 EXPECT_GE(vp9.spatial_idx, 0); // S
2697 EXPECT_LT(vp9.spatial_idx, vp9_settings_.numberOfSpatialLayers);
2698 if (vp9.ss_data_available) // V
2699 VerifySsData(vp9);
2700
2701 if (frames_sent_ == 0)
2702 EXPECT_FALSE(vp9.inter_pic_predicted); // P
2703
2704 if (!vp9.inter_pic_predicted) {
2705 EXPECT_TRUE(vp9.temporal_idx == 0 || vp9.temporal_idx == kNoTemporalIdx);
2706 EXPECT_FALSE(vp9.temporal_up_switch);
2707 }
2708 }
2709
2710 // Scalability structure (SS).
2711 //
2712 // +-+-+-+-+-+-+-+-+
2713 // V: | N_S |Y|G|-|-|-|
2714 // +-+-+-+-+-+-+-+-+
2715 // Y: | WIDTH | N_S + 1 times
2716 // +-+-+-+-+-+-+-+-+
2717 // | HEIGHT |
2718 // +-+-+-+-+-+-+-+-+
2719 // G: | N_G |
2720 // +-+-+-+-+-+-+-+-+
2721 // N_G: | T |U| R |-|-| N_G times
2722 // +-+-+-+-+-+-+-+-+
2723 // | P_DIFF | R times
2724 // +-+-+-+-+-+-+-+-+
2725 void VerifySsData(const RTPVideoHeaderVP9& vp9) const {
2726 EXPECT_TRUE(vp9.ss_data_available); // V
2727 EXPECT_EQ(vp9_settings_.numberOfSpatialLayers, // N_S + 1
2728 vp9.num_spatial_layers);
2729 EXPECT_TRUE(vp9.spatial_layer_resolution_present); // Y:1
perkjfa10b552016-10-02 23:45:26 -07002730 int expected_width = expected_width_;
2731 int expected_height = expected_height_;
Peter Boström02083222016-06-14 12:52:54 +02002732 for (int i = static_cast<int>(vp9.num_spatial_layers) - 1; i >= 0; --i) {
Åsa Perssonff24c042015-12-04 10:58:08 +01002733 EXPECT_EQ(expected_width, vp9.width[i]); // WIDTH
2734 EXPECT_EQ(expected_height, vp9.height[i]); // HEIGHT
2735 expected_width /= 2;
2736 expected_height /= 2;
2737 }
2738 }
2739
2740 void CompareConsecutiveFrames(const RTPHeader& header,
2741 const RTPVideoHeader& video) const {
2742 const RTPVideoHeaderVP9& vp9 = video.codecHeader.VP9;
2743
2744 bool new_frame = packets_sent_ == 0 ||
2745 IsNewerTimestamp(header.timestamp, last_header_.timestamp);
2746 EXPECT_EQ(new_frame, video.isFirstPacket);
2747 if (!new_frame) {
2748 EXPECT_FALSE(last_header_.markerBit);
2749 EXPECT_EQ(last_header_.timestamp, header.timestamp);
2750 EXPECT_EQ(last_vp9_.picture_id, vp9.picture_id);
2751 EXPECT_EQ(last_vp9_.temporal_idx, vp9.temporal_idx);
2752 EXPECT_EQ(last_vp9_.tl0_pic_idx, vp9.tl0_pic_idx);
2753 VerifySpatialIdxWithinFrame(vp9);
2754 return;
2755 }
2756 // New frame.
2757 EXPECT_TRUE(vp9.beginning_of_frame);
2758
2759 // Compare with last packet in previous frame.
2760 if (frames_sent_ == 0)
2761 return;
2762 EXPECT_TRUE(last_vp9_.end_of_frame);
2763 EXPECT_TRUE(last_header_.markerBit);
2764 EXPECT_TRUE(ContinuousPictureId(vp9));
2765 VerifyTl0Idx(vp9);
2766 }
2767
kwiberg27f982b2016-03-01 11:52:33 -08002768 std::unique_ptr<VP9Encoder> vp9_encoder_;
philipel0f9af012015-09-01 07:01:51 -07002769 VideoCodecVP9 vp9_settings_;
Åsa Perssonff24c042015-12-04 10:58:08 +01002770 webrtc::VideoEncoderConfig encoder_config_;
2771 RTPHeader last_header_;
2772 RTPVideoHeaderVP9 last_vp9_;
2773 size_t packets_sent_;
2774 size_t frames_sent_;
perkjfa10b552016-10-02 23:45:26 -07002775 int expected_width_;
2776 int expected_height_;
philipel0f9af012015-09-01 07:01:51 -07002777};
2778
Åsa Perssonff24c042015-12-04 10:58:08 +01002779TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl1SLayers) {
2780 const uint8_t kNumTemporalLayers = 1;
2781 const uint8_t kNumSpatialLayers = 1;
2782 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2783}
2784
2785TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl1SLayers) {
2786 const uint8_t kNumTemporalLayers = 2;
2787 const uint8_t kNumSpatialLayers = 1;
2788 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2789}
2790
2791TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl1SLayers) {
2792 const uint8_t kNumTemporalLayers = 3;
2793 const uint8_t kNumSpatialLayers = 1;
2794 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2795}
2796
2797TEST_F(VideoSendStreamTest, Vp9NonFlexMode_1Tl2SLayers) {
2798 const uint8_t kNumTemporalLayers = 1;
2799 const uint8_t kNumSpatialLayers = 2;
2800 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2801}
2802
2803TEST_F(VideoSendStreamTest, Vp9NonFlexMode_2Tl2SLayers) {
2804 const uint8_t kNumTemporalLayers = 2;
2805 const uint8_t kNumSpatialLayers = 2;
2806 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2807}
2808
2809TEST_F(VideoSendStreamTest, Vp9NonFlexMode_3Tl2SLayers) {
2810 const uint8_t kNumTemporalLayers = 3;
2811 const uint8_t kNumSpatialLayers = 2;
2812 TestVp9NonFlexMode(kNumTemporalLayers, kNumSpatialLayers);
2813}
2814
2815void VideoSendStreamTest::TestVp9NonFlexMode(uint8_t num_temporal_layers,
2816 uint8_t num_spatial_layers) {
2817 static const size_t kNumFramesToSend = 100;
2818 // Set to < kNumFramesToSend and coprime to length of temporal layer
2819 // structures to verify temporal id reset on key frame.
2820 static const int kKeyFrameInterval = 31;
2821 class NonFlexibleMode : public Vp9HeaderObserver {
2822 public:
2823 NonFlexibleMode(uint8_t num_temporal_layers, uint8_t num_spatial_layers)
2824 : num_temporal_layers_(num_temporal_layers),
2825 num_spatial_layers_(num_spatial_layers),
2826 l_field_(num_temporal_layers > 1 || num_spatial_layers > 1) {}
stefanff483612015-12-21 03:14:00 -08002827 void ModifyVideoConfigsHook(
philipel0f9af012015-09-01 07:01:51 -07002828 VideoSendStream::Config* send_config,
2829 std::vector<VideoReceiveStream::Config>* receive_configs,
2830 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01002831 vp9_settings_.flexibleMode = false;
2832 vp9_settings_.frameDroppingOn = false;
2833 vp9_settings_.keyFrameInterval = kKeyFrameInterval;
2834 vp9_settings_.numberOfTemporalLayers = num_temporal_layers_;
2835 vp9_settings_.numberOfSpatialLayers = num_spatial_layers_;
philipel0f9af012015-09-01 07:01:51 -07002836 }
2837
Åsa Perssonff24c042015-12-04 10:58:08 +01002838 void InspectHeader(const RTPVideoHeaderVP9& vp9) override {
2839 bool ss_data_expected = !vp9.inter_pic_predicted &&
2840 vp9.beginning_of_frame && vp9.spatial_idx == 0;
2841 EXPECT_EQ(ss_data_expected, vp9.ss_data_available);
2842 EXPECT_EQ(vp9.spatial_idx > 0, vp9.inter_layer_predicted); // D
asapersson38bb8ad2015-12-14 01:41:19 -08002843 EXPECT_EQ(!vp9.inter_pic_predicted,
2844 frames_sent_ % kKeyFrameInterval == 0);
Åsa Perssonff24c042015-12-04 10:58:08 +01002845
2846 if (IsNewPictureId(vp9)) {
2847 EXPECT_EQ(0, vp9.spatial_idx);
2848 EXPECT_EQ(num_spatial_layers_ - 1, last_vp9_.spatial_idx);
2849 }
2850
2851 VerifyFixedTemporalLayerStructure(vp9,
2852 l_field_ ? num_temporal_layers_ : 0);
2853
2854 if (frames_sent_ > kNumFramesToSend)
Peter Boström5811a392015-12-10 13:02:50 +01002855 observation_complete_.Set();
philipel0f9af012015-09-01 07:01:51 -07002856 }
Åsa Perssonff24c042015-12-04 10:58:08 +01002857 const uint8_t num_temporal_layers_;
2858 const uint8_t num_spatial_layers_;
2859 const bool l_field_;
2860 } test(num_temporal_layers, num_spatial_layers);
philipelcfc319b2015-11-10 07:17:23 -08002861
stefane74eef12016-01-08 06:47:13 -08002862 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08002863}
2864
asaperssond9f641e2016-01-21 01:11:35 -08002865TEST_F(VideoSendStreamTest, Vp9NonFlexModeSmallResolution) {
2866 static const size_t kNumFramesToSend = 50;
2867 static const int kWidth = 4;
2868 static const int kHeight = 4;
2869 class NonFlexibleModeResolution : public Vp9HeaderObserver {
2870 void ModifyVideoConfigsHook(
2871 VideoSendStream::Config* send_config,
2872 std::vector<VideoReceiveStream::Config>* receive_configs,
2873 VideoEncoderConfig* encoder_config) override {
2874 vp9_settings_.flexibleMode = false;
2875 vp9_settings_.numberOfTemporalLayers = 1;
2876 vp9_settings_.numberOfSpatialLayers = 1;
2877
perkjfa10b552016-10-02 23:45:26 -07002878 EXPECT_EQ(1u, encoder_config->number_of_streams);
asaperssond9f641e2016-01-21 01:11:35 -08002879 }
2880
2881 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
2882 if (frames_sent_ > kNumFramesToSend)
2883 observation_complete_.Set();
2884 }
perkjfa10b552016-10-02 23:45:26 -07002885
2886 void ModifyVideoCaptureStartResolution(int* width,
2887 int* height,
2888 int* frame_rate) override {
2889 expected_width_ = kWidth;
2890 expected_height_ = kHeight;
2891 *width = kWidth;
2892 *height = kHeight;
2893 }
asaperssond9f641e2016-01-21 01:11:35 -08002894 } test;
2895
2896 RunBaseTest(&test);
2897}
2898
Åsa Perssonff24c042015-12-04 10:58:08 +01002899TEST_F(VideoSendStreamTest, Vp9FlexModeRefCount) {
2900 class FlexibleMode : public Vp9HeaderObserver {
stefanff483612015-12-21 03:14:00 -08002901 void ModifyVideoConfigsHook(
philipelcfc319b2015-11-10 07:17:23 -08002902 VideoSendStream::Config* send_config,
2903 std::vector<VideoReceiveStream::Config>* receive_configs,
2904 VideoEncoderConfig* encoder_config) override {
Åsa Perssonff24c042015-12-04 10:58:08 +01002905 encoder_config->content_type = VideoEncoderConfig::ContentType::kScreen;
philipelcfc319b2015-11-10 07:17:23 -08002906 vp9_settings_.flexibleMode = true;
Åsa Perssonff24c042015-12-04 10:58:08 +01002907 vp9_settings_.numberOfTemporalLayers = 1;
2908 vp9_settings_.numberOfSpatialLayers = 2;
philipelcfc319b2015-11-10 07:17:23 -08002909 }
2910
Åsa Perssonff24c042015-12-04 10:58:08 +01002911 void InspectHeader(const RTPVideoHeaderVP9& vp9_header) override {
2912 EXPECT_TRUE(vp9_header.flexible_mode);
2913 EXPECT_EQ(kNoTl0PicIdx, vp9_header.tl0_pic_idx);
2914 if (vp9_header.inter_pic_predicted) {
2915 EXPECT_GT(vp9_header.num_ref_pics, 0u);
Peter Boström5811a392015-12-10 13:02:50 +01002916 observation_complete_.Set();
philipelcfc319b2015-11-10 07:17:23 -08002917 }
2918 }
2919 } test;
2920
stefane74eef12016-01-08 06:47:13 -08002921 RunBaseTest(&test);
philipelcfc319b2015-11-10 07:17:23 -08002922}
Peter Boström12996152016-05-14 02:03:18 +02002923#endif // !defined(RTC_DISABLE_VP9)
philipelcfc319b2015-11-10 07:17:23 -08002924
perkj803d97f2016-11-01 11:45:46 -07002925void VideoSendStreamTest::TestRequestSourceRotateVideo(
2926 bool support_orientation_ext) {
2927 CreateSenderCall(Call::Config(&event_log_));
2928
2929 test::NullTransport transport;
2930 CreateSendConfig(1, 0, &transport);
2931 video_send_config_.rtp.extensions.clear();
2932 if (support_orientation_ext) {
2933 video_send_config_.rtp.extensions.push_back(
2934 RtpExtension(RtpExtension::kVideoRotationUri, 1));
2935 }
2936
2937 CreateVideoStreams();
2938 test::FrameForwarder forwarder;
2939 video_send_stream_->SetSource(
2940 &forwarder, VideoSendStream::DegradationPreference::kBalanced);
2941
2942 EXPECT_TRUE(forwarder.sink_wants().rotation_applied !=
2943 support_orientation_ext);
2944
2945 DestroyStreams();
2946}
2947
2948TEST_F(VideoSendStreamTest,
2949 RequestSourceRotateIfVideoOrientationExtensionNotSupported) {
2950 TestRequestSourceRotateVideo(false);
2951}
2952
2953TEST_F(VideoSendStreamTest,
2954 DoNotRequestsRotationIfVideoOrientationExtensionSupported) {
2955 TestRequestSourceRotateVideo(true);
2956}
2957
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00002958} // namespace webrtc