blob: 22606a64461fe4c3b63f9bc434b04d3cde9d2b64 [file] [log] [blame]
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * 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.
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00009 */
10
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +000011#include <algorithm>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000012#include <map>
kwiberg686a8ef2016-02-26 03:00:35 -080013#include <memory>
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000014#include <vector>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000015
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +000016#include "webrtc/base/arraysize.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000017#include "webrtc/base/gunit.h"
18#include "webrtc/base/stringutils.h"
magjed725e4842016-11-16 00:48:13 -080019#include "webrtc/common_video/h264/profile_level_id.h"
skvlad11a9cbf2016-10-07 11:53:05 -070020#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
magjed5dfac562016-11-25 03:56:37 -080021#include "webrtc/media/base/mediaconstants.h"
kjellandera96e2d72016-02-04 23:52:28 -080022#include "webrtc/media/base/testutils.h"
23#include "webrtc/media/base/videoengine_unittest.h"
sprang429600d2017-01-26 06:12:26 -080024#include "webrtc/media/engine/constants.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010025#include "webrtc/media/engine/fakewebrtccall.h"
26#include "webrtc/media/engine/fakewebrtcvideoengine.h"
27#include "webrtc/media/engine/simulcast.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010028#include "webrtc/media/engine/webrtcvideoengine2.h"
29#include "webrtc/media/engine/webrtcvoiceengine.h"
stefanc1aeaf02015-10-15 07:26:07 -070030#include "webrtc/test/field_trial.h"
pbos@webrtc.org42684be2014-10-03 11:25:45 +000031#include "webrtc/video_encoder.h"
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000032
isheriff6f8d6862016-05-26 11:24:55 -070033using webrtc::RtpExtension;
34
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000035namespace {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000036static const int kDefaultQpMax = 56;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000037
noahricd10a68e2015-07-10 11:27:55 -070038static const uint8_t kRedRtxPayloadType = 125;
39
Peter Boström0c4e06b2015-10-07 12:23:21 +020040static const uint32_t kSsrcs1[] = {1};
41static const uint32_t kSsrcs3[] = {1, 2, 3};
42static const uint32_t kRtxSsrcs1[] = {4};
brandtr468da7c2016-11-22 02:16:47 -080043static const uint32_t kFlexfecSsrc = 5;
Peter Boström0c4e06b2015-10-07 12:23:21 +020044static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE;
pbos@webrtc.org3c107582014-07-20 15:27:35 +000045static const char kUnsupportedExtensionName[] =
46 "urn:ietf:params:rtp-hdrext:unsupported";
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000047
magjed509e4fe2016-11-18 01:34:11 -080048cricket::VideoCodec RemoveFeedbackParams(cricket::VideoCodec&& codec) {
49 codec.feedback_params = cricket::FeedbackParams();
50 return codec;
51}
52
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000053void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) {
54 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
55 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
56 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
57 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
58 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
59 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
60 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
stefan43edf0f2015-11-20 18:05:48 -080061 cricket::kRtcpFbParamTransportCc, cricket::kParamValueEmpty)));
62 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000063 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
64}
65
magjed725e4842016-11-16 00:48:13 -080066// Return true if any codec in |codecs| is an RTX codec with associated payload
67// type |payload_type|.
68bool HasRtxCodec(const std::vector<cricket::VideoCodec>& codecs,
69 int payload_type) {
70 for (const cricket::VideoCodec& codec : codecs) {
71 int associated_payload_type;
72 if (cricket::CodecNamesEq(codec.name.c_str(), "rtx") &&
73 codec.GetParam(cricket::kCodecParamAssociatedPayloadType,
74 &associated_payload_type) &&
75 associated_payload_type == payload_type) {
76 return true;
77 }
78 }
79 return false;
80}
81
brandtrffc61182016-11-28 06:02:22 -080082rtc::scoped_refptr<webrtc::VideoFrameBuffer> CreateBlackFrameBuffer(
nisse64ec8f82016-09-27 00:17:25 -070083 int width,
84 int height) {
85 rtc::scoped_refptr<webrtc::I420Buffer> buffer =
86 webrtc::I420Buffer::Create(width, height);
nisseaf916892017-01-10 07:44:26 -080087 webrtc::I420Buffer::SetBlack(buffer);
nisse64ec8f82016-09-27 00:17:25 -070088 return buffer;
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +000089}
90
Shao Changbine62202f2015-04-21 20:24:50 +080091void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config,
92 const std::map<int, int>& rtx_types) {
93 std::map<int, int>::const_iterator it;
94 it = rtx_types.find(config.encoder_settings.payload_type);
95 EXPECT_TRUE(it != rtx_types.end() &&
96 it->second == config.rtp.rtx.payload_type);
97
brandtrb5f2c3f2016-10-04 23:28:39 -070098 if (config.rtp.ulpfec.red_rtx_payload_type != -1) {
99 it = rtx_types.find(config.rtp.ulpfec.red_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800100 EXPECT_TRUE(it != rtx_types.end() &&
brandtrb5f2c3f2016-10-04 23:28:39 -0700101 it->second == config.rtp.ulpfec.red_rtx_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800102 }
103}
kthelgason83399ca2017-02-01 01:31:52 -0800104
105cricket::MediaConfig GetMediaConfig() {
106 cricket::MediaConfig media_config;
107 media_config.video.enable_cpu_overuse_detection = false;
108 return media_config;
109}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000110} // namespace
111
112namespace cricket {
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000113class WebRtcVideoEngine2Test : public ::testing::Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000114 public:
stefanc1aeaf02015-10-15 07:26:07 -0700115 WebRtcVideoEngine2Test() : WebRtcVideoEngine2Test("") {}
116 explicit WebRtcVideoEngine2Test(const char* field_trials)
stefanc1aeaf02015-10-15 07:26:07 -0700117 : override_field_trials_(field_trials),
skvlad11a9cbf2016-10-07 11:53:05 -0700118 call_(webrtc::Call::Create(webrtc::Call::Config(&event_log_))),
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200119 engine_() {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000120 std::vector<VideoCodec> engine_codecs = engine_.codecs();
henrikg91d6ede2015-09-17 00:24:34 -0700121 RTC_DCHECK(!engine_codecs.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000122 bool codec_set = false;
magjed509e4fe2016-11-18 01:34:11 -0800123 for (const cricket::VideoCodec& codec : engine_codecs) {
124 if (codec.name == "rtx") {
Shao Changbine62202f2015-04-21 20:24:50 +0800125 int associated_payload_type;
magjed509e4fe2016-11-18 01:34:11 -0800126 if (codec.GetParam(kCodecParamAssociatedPayloadType,
127 &associated_payload_type)) {
128 default_apt_rtx_types_[associated_payload_type] = codec.id;
Shao Changbine62202f2015-04-21 20:24:50 +0800129 }
magjed509e4fe2016-11-18 01:34:11 -0800130 } else if (!codec_set && codec.name != "red" && codec.name != "ulpfec") {
131 default_codec_ = codec;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000132 codec_set = true;
133 }
134 }
135
henrikg91d6ede2015-09-17 00:24:34 -0700136 RTC_DCHECK(codec_set);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000137 }
138
139 protected:
magjed509e4fe2016-11-18 01:34:11 -0800140 // Find the codec in the engine with the given name. The codec must be
141 // present.
142 cricket::VideoCodec GetEngineCodec(const std::string& name);
143
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000144 VideoMediaChannel* SetUpForExternalEncoderFactory(
magjed509e4fe2016-11-18 01:34:11 -0800145 cricket::WebRtcVideoEncoderFactory* encoder_factory);
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000146
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000147 VideoMediaChannel* SetUpForExternalDecoderFactory(
148 cricket::WebRtcVideoDecoderFactory* decoder_factory,
149 const std::vector<VideoCodec>& codecs);
150
Peter Boströme4499152016-02-05 11:13:28 +0100151 void TestExtendedEncoderOveruse(bool use_external_encoder);
152
stefanc1aeaf02015-10-15 07:26:07 -0700153 webrtc::test::ScopedFieldTrials override_field_trials_;
skvlad11a9cbf2016-10-07 11:53:05 -0700154 webrtc::RtcEventLogNullImpl event_log_;
pbos@webrtc.orgf1f0d9a2015-03-02 13:30:15 +0000155 // Used in WebRtcVideoEngine2VoiceTest, but defined here so it's properly
156 // initialized when the constructor is called.
kwiberg686a8ef2016-02-26 03:00:35 -0800157 std::unique_ptr<webrtc::Call> call_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000158 WebRtcVideoEngine2 engine_;
159 VideoCodec default_codec_;
Shao Changbine62202f2015-04-21 20:24:50 +0800160 std::map<int, int> default_apt_rtx_types_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000161};
162
Peter Boström12996152016-05-14 02:03:18 +0200163TEST_F(WebRtcVideoEngine2Test, AnnouncesVp9AccordingToBuildFlags) {
164 bool claims_vp9_support = false;
165 for (const cricket::VideoCodec& codec : engine_.codecs()) {
166 if (codec.name == "VP9") {
167 claims_vp9_support = true;
168 break;
169 }
170 }
171#if defined(RTC_DISABLE_VP9)
172 EXPECT_FALSE(claims_vp9_support);
173#else
174 EXPECT_TRUE(claims_vp9_support);
175#endif // defined(RTC_DISABLE_VP9)
176}
177
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000178TEST_F(WebRtcVideoEngine2Test, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
179 std::vector<VideoCodec> engine_codecs = engine_.codecs();
180 for (size_t i = 0; i < engine_codecs.size(); ++i) {
181 if (engine_codecs[i].name != kRtxCodecName)
182 continue;
183 int associated_payload_type;
184 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000185 &associated_payload_type));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000186 EXPECT_EQ(default_codec_.id, associated_payload_type);
187 return;
188 }
189 FAIL() << "No RTX codec found among default codecs.";
190}
191
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000192TEST_F(WebRtcVideoEngine2Test, SupportsTimestampOffsetHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100193 RtpCapabilities capabilities = engine_.GetCapabilities();
194 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700195 for (const RtpExtension& extension : capabilities.header_extensions) {
196 if (extension.uri == RtpExtension::kTimestampOffsetUri) {
197 EXPECT_EQ(RtpExtension::kTimestampOffsetDefaultId, extension.id);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000198 return;
199 }
200 }
201 FAIL() << "Timestamp offset extension not in header-extension list.";
202}
203
204TEST_F(WebRtcVideoEngine2Test, SupportsAbsoluteSenderTimeHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100205 RtpCapabilities capabilities = engine_.GetCapabilities();
206 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700207 for (const RtpExtension& extension : capabilities.header_extensions) {
208 if (extension.uri == RtpExtension::kAbsSendTimeUri) {
209 EXPECT_EQ(RtpExtension::kAbsSendTimeDefaultId, extension.id);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000210 return;
211 }
212 }
213 FAIL() << "Absolute Sender Time extension not in header-extension list.";
214}
215
Stefan Holmer06a5e1a2016-09-02 12:36:49 +0200216TEST_F(WebRtcVideoEngine2Test, SupportsTransportSequenceNumberHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100217 RtpCapabilities capabilities = engine_.GetCapabilities();
218 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700219 for (const RtpExtension& extension : capabilities.header_extensions) {
220 if (extension.uri == RtpExtension::kTransportSequenceNumberUri) {
221 EXPECT_EQ(RtpExtension::kTransportSequenceNumberDefaultId, extension.id);
stefanc1aeaf02015-10-15 07:26:07 -0700222 return;
223 }
224 }
225 FAIL() << "Transport sequence number extension not in header-extension list.";
226}
227
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700228TEST_F(WebRtcVideoEngine2Test, SupportsVideoRotationHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100229 RtpCapabilities capabilities = engine_.GetCapabilities();
230 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700231 for (const RtpExtension& extension : capabilities.header_extensions) {
232 if (extension.uri == RtpExtension::kVideoRotationUri) {
233 EXPECT_EQ(RtpExtension::kVideoRotationDefaultId, extension.id);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700234 return;
235 }
236 }
237 FAIL() << "Video Rotation extension not in header-extension list.";
238}
239
240TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionBeforeCapturer) {
241 // Allocate the capturer first to prevent early destruction before channel's
242 // dtor is called.
243 cricket::FakeVideoCapturer capturer;
244
245 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700246 encoder_factory.AddSupportedVideoCodecType("VP8");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700247
kwiberg686a8ef2016-02-26 03:00:35 -0800248 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800249 SetUpForExternalEncoderFactory(&encoder_factory));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700250 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
251
252 // Add CVO extension.
253 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800254 cricket::VideoSendParameters parameters;
255 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200256 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700257 RtpExtension(RtpExtension::kVideoRotationUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200258 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700259
260 // Set capturer.
deadbeef5a4a75a2016-06-02 16:23:38 -0700261 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700262
263 // Verify capturer has turned off applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700264 EXPECT_FALSE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700265
266 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200267 parameters.extensions.clear();
268 EXPECT_TRUE(channel->SetSendParameters(parameters));
nisse47ac4622016-05-25 08:47:01 -0700269 EXPECT_TRUE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700270}
271
perkj91e1c152016-03-02 05:34:00 -0800272TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionBeforeAddSendStream) {
273 // Allocate the capturer first to prevent early destruction before channel's
274 // dtor is called.
275 cricket::FakeVideoCapturer capturer;
276
277 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700278 encoder_factory.AddSupportedVideoCodecType("VP8");
perkj91e1c152016-03-02 05:34:00 -0800279
280 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800281 SetUpForExternalEncoderFactory(&encoder_factory));
perkj91e1c152016-03-02 05:34:00 -0800282 // Add CVO extension.
283 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800284 cricket::VideoSendParameters parameters;
285 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj91e1c152016-03-02 05:34:00 -0800286 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700287 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkj91e1c152016-03-02 05:34:00 -0800288 EXPECT_TRUE(channel->SetSendParameters(parameters));
289 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
290
291 // Set capturer.
deadbeef5a4a75a2016-06-02 16:23:38 -0700292 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
perkj91e1c152016-03-02 05:34:00 -0800293
294 // Verify capturer has turned off applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700295 EXPECT_FALSE(capturer.apply_rotation());
perkj91e1c152016-03-02 05:34:00 -0800296}
297
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700298TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionAfterCapturer) {
299 cricket::FakeVideoCapturer capturer;
300
301 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700302 encoder_factory.AddSupportedVideoCodecType("VP8");
303 encoder_factory.AddSupportedVideoCodecType("VP9");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700304
kwiberg686a8ef2016-02-26 03:00:35 -0800305 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800306 SetUpForExternalEncoderFactory(&encoder_factory));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700307 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
308
309 // Set capturer.
deadbeef5a4a75a2016-06-02 16:23:38 -0700310 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700311
perkjcaafdba2016-03-20 07:34:29 -0700312 // Verify capturer has turned on applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700313 EXPECT_TRUE(capturer.apply_rotation());
perkjcaafdba2016-03-20 07:34:29 -0700314
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700315 // Add CVO extension.
316 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800317 cricket::VideoSendParameters parameters;
318 parameters.codecs.push_back(GetEngineCodec("VP8"));
319 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200320 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700321 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkjcaafdba2016-03-20 07:34:29 -0700322 // Also remove the first codec to trigger a codec change as well.
323 parameters.codecs.erase(parameters.codecs.begin());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200324 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700325
326 // Verify capturer has turned off applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700327 EXPECT_FALSE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700328
329 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200330 parameters.extensions.clear();
331 EXPECT_TRUE(channel->SetSendParameters(parameters));
nisse47ac4622016-05-25 08:47:01 -0700332 EXPECT_TRUE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700333}
334
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000335TEST_F(WebRtcVideoEngine2Test, SetSendFailsBeforeSettingCodecs) {
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200336 engine_.Init();
kwiberg686a8ef2016-02-26 03:00:35 -0800337 std::unique_ptr<VideoMediaChannel> channel(
kthelgason83399ca2017-02-01 01:31:52 -0800338 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000339
340 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
341
342 EXPECT_FALSE(channel->SetSend(true))
343 << "Channel should not start without codecs.";
344 EXPECT_TRUE(channel->SetSend(false))
345 << "Channel should be stoppable even without set codecs.";
346}
347
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000348TEST_F(WebRtcVideoEngine2Test, GetStatsWithoutSendCodecsSetDoesNotCrash) {
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200349 engine_.Init();
kwiberg686a8ef2016-02-26 03:00:35 -0800350 std::unique_ptr<VideoMediaChannel> channel(
kthelgason83399ca2017-02-01 01:31:52 -0800351 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000352 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
353 VideoMediaInfo info;
354 channel->GetStats(&info);
355}
356
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000357TEST_F(WebRtcVideoEngine2Test, UseExternalFactoryForVp8WhenSupported) {
358 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700359 encoder_factory.AddSupportedVideoCodecType("VP8");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000360
kwiberg686a8ef2016-02-26 03:00:35 -0800361 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800362 SetUpForExternalEncoderFactory(&encoder_factory));
Sergey Ulanove2b15012016-11-22 16:08:30 -0800363 channel->OnReadyToSend(true);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000364
365 EXPECT_TRUE(
366 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Per21d45d22016-10-30 21:37:57 +0100367 EXPECT_EQ(0, encoder_factory.GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000368 EXPECT_TRUE(channel->SetSend(true));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000369 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700370 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000371 EXPECT_EQ(cricket::CS_RUNNING,
372 capturer.Start(capturer.GetSupportedFormats()->front()));
373 EXPECT_TRUE(capturer.CaptureFrame());
Per21d45d22016-10-30 21:37:57 +0100374 // Sending one frame will have allocate the encoder.
375 ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(1));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000376 EXPECT_TRUE_WAIT(encoder_factory.encoders()[0]->GetNumEncodedFrames() > 0,
377 kTimeout);
378
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000379 int num_created_encoders = encoder_factory.GetNumCreatedEncoders();
Per21d45d22016-10-30 21:37:57 +0100380 EXPECT_EQ(num_created_encoders, 1);
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000381
382 // Setting codecs of the same type should not reallocate any encoders
383 // (expecting a no-op).
magjed509e4fe2016-11-18 01:34:11 -0800384 cricket::VideoSendParameters parameters;
385 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200386 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000387 EXPECT_EQ(num_created_encoders, encoder_factory.GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000388
389 // Remove stream previously added to free the external encoder instance.
390 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
391 EXPECT_EQ(0u, encoder_factory.encoders().size());
392}
393
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700394// Test that when an external encoder factory supports a codec we don't
395// internally support, we still add an RTX codec for it.
396// TODO(deadbeef): Currently this test is only effective if WebRTC is
397// built with no internal H264 support. This test should be updated
398// if/when we start adding RTX codecs for unrecognized codec names.
399TEST_F(WebRtcVideoEngine2Test, RtxCodecAddedForExternalCodec) {
magjed725e4842016-11-16 00:48:13 -0800400 using webrtc::H264::ProfileLevelIdToString;
401 using webrtc::H264::ProfileLevelId;
402 using webrtc::H264::kLevel1;
403 cricket::VideoCodec h264_constrained_baseline("H264");
404 h264_constrained_baseline.params[kH264FmtpProfileLevelId] =
405 *ProfileLevelIdToString(
406 ProfileLevelId(webrtc::H264::kProfileConstrainedBaseline, kLevel1));
407 cricket::VideoCodec h264_constrained_high("H264");
408 h264_constrained_high.params[kH264FmtpProfileLevelId] =
409 *ProfileLevelIdToString(
410 ProfileLevelId(webrtc::H264::kProfileConstrainedHigh, kLevel1));
411 cricket::VideoCodec h264_high("H264");
412 h264_high.params[kH264FmtpProfileLevelId] = *ProfileLevelIdToString(
413 ProfileLevelId(webrtc::H264::kProfileHigh, kLevel1));
414
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700415 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed725e4842016-11-16 00:48:13 -0800416 encoder_factory.AddSupportedVideoCodec(h264_constrained_baseline);
417 encoder_factory.AddSupportedVideoCodec(h264_constrained_high);
418 encoder_factory.AddSupportedVideoCodec(h264_high);
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700419 engine_.SetExternalEncoderFactory(&encoder_factory);
420 engine_.Init();
421
magjed725e4842016-11-16 00:48:13 -0800422 // First figure out what payload types the test codecs got assigned.
423 const std::vector<cricket::VideoCodec> codecs = engine_.codecs();
magjed509e4fe2016-11-18 01:34:11 -0800424 // Now search for RTX codecs for them. Expect that they all have associated
425 // RTX codecs.
magjed725e4842016-11-16 00:48:13 -0800426 EXPECT_TRUE(HasRtxCodec(
427 codecs, FindMatchingCodec(codecs, h264_constrained_baseline)->id));
428 EXPECT_TRUE(HasRtxCodec(
429 codecs, FindMatchingCodec(codecs, h264_constrained_high)->id));
magjed509e4fe2016-11-18 01:34:11 -0800430 EXPECT_TRUE(HasRtxCodec(
magjed725e4842016-11-16 00:48:13 -0800431 codecs, FindMatchingCodec(codecs, h264_high)->id));
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700432}
433
Peter Boströme4499152016-02-05 11:13:28 +0100434void WebRtcVideoEngine2Test::TestExtendedEncoderOveruse(
435 bool use_external_encoder) {
436 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700437 encoder_factory.AddSupportedVideoCodecType("VP8");
kwiberg686a8ef2016-02-26 03:00:35 -0800438 std::unique_ptr<VideoMediaChannel> channel;
skvlad11a9cbf2016-10-07 11:53:05 -0700439 FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_));
Peter Boströme4499152016-02-05 11:13:28 +0100440 call_.reset(fake_call);
441 if (use_external_encoder) {
magjed509e4fe2016-11-18 01:34:11 -0800442 channel.reset(SetUpForExternalEncoderFactory(&encoder_factory));
Peter Boströme4499152016-02-05 11:13:28 +0100443 } else {
444 engine_.Init();
nisse51542be2016-02-12 02:27:06 -0800445 channel.reset(
kthelgason83399ca2017-02-01 01:31:52 -0800446 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
Peter Boströme4499152016-02-05 11:13:28 +0100447 }
448 ASSERT_TRUE(
449 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
magjed509e4fe2016-11-18 01:34:11 -0800450 cricket::VideoSendParameters parameters;
451 parameters.codecs.push_back(GetEngineCodec("VP8"));
Peter Boströme4499152016-02-05 11:13:28 +0100452 EXPECT_TRUE(channel->SetSendParameters(parameters));
453 EXPECT_TRUE(channel->SetSend(true));
454 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
455
456 EXPECT_EQ(use_external_encoder,
457 stream->GetConfig().encoder_settings.full_overuse_time);
458 // Remove stream previously added to free the external encoder instance.
459 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
460}
461
462TEST_F(WebRtcVideoEngine2Test, EnablesFullEncoderTimeForExternalEncoders) {
463 TestExtendedEncoderOveruse(true);
464}
465
466TEST_F(WebRtcVideoEngine2Test, DisablesFullEncoderTimeForNonExternalEncoders) {
467 TestExtendedEncoderOveruse(false);
468}
469
Peter Boström12996152016-05-14 02:03:18 +0200470#if !defined(RTC_DISABLE_VP9)
Peter Boström53eda3d2015-03-27 15:53:18 +0100471TEST_F(WebRtcVideoEngine2Test, CanConstructDecoderForVp9EncoderFactory) {
472 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700473 encoder_factory.AddSupportedVideoCodecType("VP9");
Peter Boström53eda3d2015-03-27 15:53:18 +0100474
kwiberg686a8ef2016-02-26 03:00:35 -0800475 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800476 SetUpForExternalEncoderFactory(&encoder_factory));
Peter Boström53eda3d2015-03-27 15:53:18 +0100477
478 EXPECT_TRUE(
479 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
480}
Peter Boström12996152016-05-14 02:03:18 +0200481#endif // !defined(RTC_DISABLE_VP9)
Peter Boström53eda3d2015-03-27 15:53:18 +0100482
qiangchenc27d89f2015-07-16 10:27:16 -0700483TEST_F(WebRtcVideoEngine2Test, PropagatesInputFrameTimestamp) {
484 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700485 encoder_factory.AddSupportedVideoCodecType("VP8");
skvlad11a9cbf2016-10-07 11:53:05 -0700486 FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200487 call_.reset(fake_call);
kwiberg686a8ef2016-02-26 03:00:35 -0800488 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800489 SetUpForExternalEncoderFactory(&encoder_factory));
qiangchenc27d89f2015-07-16 10:27:16 -0700490
491 EXPECT_TRUE(
492 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
493
494 FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700495 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
qiangchenc27d89f2015-07-16 10:27:16 -0700496 capturer.Start(cricket::VideoFormat(1280, 720,
497 cricket::VideoFormat::FpsToInterval(60),
498 cricket::FOURCC_I420));
499 channel->SetSend(true);
500
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200501 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
qiangchenc27d89f2015-07-16 10:27:16 -0700502
503 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700504 int64_t last_timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700505 for (int i = 0; i < 10; i++) {
506 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700507 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700508 int64_t interval = timestamp - last_timestamp;
509
510 // Precision changes from nanosecond to millisecond.
511 // Allow error to be no more than 1.
512 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1);
513
514 last_timestamp = timestamp;
515 }
516
517 capturer.Start(cricket::VideoFormat(1280, 720,
518 cricket::VideoFormat::FpsToInterval(30),
519 cricket::FOURCC_I420));
520
521 EXPECT_TRUE(capturer.CaptureFrame());
522 last_timestamp = stream->GetLastTimestamp();
523 for (int i = 0; i < 10; i++) {
524 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700525 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700526 int64_t interval = timestamp - last_timestamp;
527
528 // Precision changes from nanosecond to millisecond.
529 // Allow error to be no more than 1.
530 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1);
531
532 last_timestamp = timestamp;
533 }
534
535 // Remove stream previously added to free the external encoder instance.
536 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
537}
538
magjed509e4fe2016-11-18 01:34:11 -0800539cricket::VideoCodec WebRtcVideoEngine2Test::GetEngineCodec(
540 const std::string& name) {
541 for (const cricket::VideoCodec& engine_codec : engine_.codecs()) {
542 if (CodecNamesEq(name, engine_codec.name))
543 return engine_codec;
544 }
545 // This point should never be reached.
546 ADD_FAILURE() << "Unrecognized codec name: " << name;
547 return cricket::VideoCodec();
548}
549
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000550VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalEncoderFactory(
magjed509e4fe2016-11-18 01:34:11 -0800551 cricket::WebRtcVideoEncoderFactory* encoder_factory) {
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000552 engine_.SetExternalEncoderFactory(encoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200553 engine_.Init();
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000554
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000555 VideoMediaChannel* channel =
kthelgason83399ca2017-02-01 01:31:52 -0800556 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200557 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800558 // We need to look up the codec in the engine to get the correct payload type.
559 for (const VideoCodec& codec : encoder_factory->supported_codecs())
560 parameters.codecs.push_back(GetEngineCodec(codec.name));
561
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200562 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000563
564 return channel;
565}
566
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000567VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalDecoderFactory(
568 cricket::WebRtcVideoDecoderFactory* decoder_factory,
569 const std::vector<VideoCodec>& codecs) {
570 engine_.SetExternalDecoderFactory(decoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200571 engine_.Init();
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000572
573 VideoMediaChannel* channel =
kthelgason83399ca2017-02-01 01:31:52 -0800574 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200575 cricket::VideoRecvParameters parameters;
576 parameters.codecs = codecs;
577 EXPECT_TRUE(channel->SetRecvParameters(parameters));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000578
579 return channel;
580}
581
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000582TEST_F(WebRtcVideoEngine2Test, UsesSimulcastAdapterForVp8Factories) {
583 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700584 encoder_factory.AddSupportedVideoCodecType("VP8");
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000585
kwiberg686a8ef2016-02-26 03:00:35 -0800586 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800587 SetUpForExternalEncoderFactory(&encoder_factory));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000588
Peter Boström0c4e06b2015-10-07 12:23:21 +0200589 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000590
591 EXPECT_TRUE(
592 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
593 EXPECT_TRUE(channel->SetSend(true));
594
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000595 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700596 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, &capturer));
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000597 EXPECT_EQ(cricket::CS_RUNNING,
598 capturer.Start(capturer.GetSupportedFormats()->front()));
599 EXPECT_TRUE(capturer.CaptureFrame());
600
pbos14fe7082016-04-20 06:35:56 -0700601 ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(2));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000602
603 // Verify that encoders are configured for simulcast through adapter
604 // (increasing resolution and only configured to send one stream each).
605 int prev_width = -1;
606 for (size_t i = 0; i < encoder_factory.encoders().size(); ++i) {
pbos14fe7082016-04-20 06:35:56 -0700607 ASSERT_TRUE(encoder_factory.encoders()[i]->WaitForInitEncode());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000608 webrtc::VideoCodec codec_settings =
609 encoder_factory.encoders()[i]->GetCodecSettings();
610 EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
611 EXPECT_GT(codec_settings.width, prev_width);
612 prev_width = codec_settings.width;
613 }
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000614
deadbeef5a4a75a2016-06-02 16:23:38 -0700615 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, nullptr));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000616
617 channel.reset();
618 ASSERT_EQ(0u, encoder_factory.encoders().size());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000619}
620
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000621TEST_F(WebRtcVideoEngine2Test, ChannelWithExternalH264CanChangeToInternalVp8) {
622 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700623 encoder_factory.AddSupportedVideoCodecType("H264");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000624
kwiberg686a8ef2016-02-26 03:00:35 -0800625 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800626 SetUpForExternalEncoderFactory(&encoder_factory));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000627
628 EXPECT_TRUE(
629 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
630 ASSERT_EQ(1u, encoder_factory.encoders().size());
631
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200632 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800633 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200634 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000635 ASSERT_EQ(0u, encoder_factory.encoders().size());
636}
637
638TEST_F(WebRtcVideoEngine2Test,
639 DontUseExternalEncoderFactoryForUnsupportedCodecs) {
640 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700641 encoder_factory.AddSupportedVideoCodecType("H264");
magjed509e4fe2016-11-18 01:34:11 -0800642
643 engine_.SetExternalEncoderFactory(&encoder_factory);
644 engine_.Init();
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000645
kwiberg686a8ef2016-02-26 03:00:35 -0800646 std::unique_ptr<VideoMediaChannel> channel(
kthelgason83399ca2017-02-01 01:31:52 -0800647 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
magjed509e4fe2016-11-18 01:34:11 -0800648 cricket::VideoSendParameters parameters;
649 parameters.codecs.push_back(GetEngineCodec("VP8"));
650 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000651
652 EXPECT_TRUE(
653 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000654 // Make sure DestroyVideoEncoder was called on the factory.
655 ASSERT_EQ(0u, encoder_factory.encoders().size());
656}
657
658TEST_F(WebRtcVideoEngine2Test,
659 UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
660 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700661 encoder_factory.AddSupportedVideoCodecType("VP8");
662 encoder_factory.AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000663
magjed509e4fe2016-11-18 01:34:11 -0800664 engine_.SetExternalEncoderFactory(&encoder_factory);
665 engine_.Init();
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000666
kwiberg686a8ef2016-02-26 03:00:35 -0800667 std::unique_ptr<VideoMediaChannel> channel(
kthelgason83399ca2017-02-01 01:31:52 -0800668 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
magjed509e4fe2016-11-18 01:34:11 -0800669 cricket::VideoSendParameters parameters;
670 parameters.codecs.push_back(GetEngineCodec("VP8"));
671 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000672
Peter Boström0c4e06b2015-10-07 12:23:21 +0200673 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000674
675 EXPECT_TRUE(
676 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
677 EXPECT_TRUE(channel->SetSend(true));
678
679 // Send a fake frame, or else the media engine will configure the simulcast
680 // encoder adapter at a low-enough size that it'll only create a single
681 // encoder layer.
682 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700683 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, &capturer));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000684 EXPECT_EQ(cricket::CS_RUNNING,
685 capturer.Start(capturer.GetSupportedFormats()->front()));
686 EXPECT_TRUE(capturer.CaptureFrame());
687
pbos14fe7082016-04-20 06:35:56 -0700688 ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(2));
689 ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000690 EXPECT_EQ(webrtc::kVideoCodecVP8,
691 encoder_factory.encoders()[0]->GetCodecSettings().codecType);
692
693 channel.reset();
694 // Make sure DestroyVideoEncoder was called on the factory.
695 EXPECT_EQ(0u, encoder_factory.encoders().size());
696}
697
698TEST_F(WebRtcVideoEngine2Test,
699 DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
700 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700701 encoder_factory.AddSupportedVideoCodecType("VP8");
702 encoder_factory.AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000703
magjed509e4fe2016-11-18 01:34:11 -0800704 engine_.SetExternalEncoderFactory(&encoder_factory);
705 engine_.Init();
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000706
kwiberg686a8ef2016-02-26 03:00:35 -0800707 std::unique_ptr<VideoMediaChannel> channel(
kthelgason83399ca2017-02-01 01:31:52 -0800708 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
magjed509e4fe2016-11-18 01:34:11 -0800709 cricket::VideoSendParameters parameters;
710 parameters.codecs.push_back(GetEngineCodec("H264"));
711 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000712
713 EXPECT_TRUE(
714 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
715 ASSERT_EQ(1u, encoder_factory.encoders().size());
Per21d45d22016-10-30 21:37:57 +0100716
717 // Send a frame of 720p. This should trigger a "real" encoder initialization.
718 cricket::VideoFormat format(
719 1280, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
720 cricket::FakeVideoCapturer capturer;
721 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
722 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format));
723 EXPECT_TRUE(capturer.CaptureFrame());
pbos14fe7082016-04-20 06:35:56 -0700724 ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000725 EXPECT_EQ(webrtc::kVideoCodecH264,
726 encoder_factory.encoders()[0]->GetCodecSettings().codecType);
727
728 channel.reset();
729 // Make sure DestroyVideoEncoder was called on the factory.
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000730 ASSERT_EQ(0u, encoder_factory.encoders().size());
731}
732
noahricfdac5162015-08-27 01:59:29 -0700733TEST_F(WebRtcVideoEngine2Test, SimulcastDisabledForH264) {
734 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700735 encoder_factory.AddSupportedVideoCodecType("H264");
noahricfdac5162015-08-27 01:59:29 -0700736
kwiberg686a8ef2016-02-26 03:00:35 -0800737 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800738 SetUpForExternalEncoderFactory(&encoder_factory));
noahricfdac5162015-08-27 01:59:29 -0700739
Peter Boström0c4e06b2015-10-07 12:23:21 +0200740 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
noahricfdac5162015-08-27 01:59:29 -0700741 EXPECT_TRUE(
742 channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs)));
Peter Boströmce23bee2016-02-02 14:14:30 +0100743
744 // Send a frame of 720p. This should trigger a "real" encoder initialization.
noahricfdac5162015-08-27 01:59:29 -0700745 cricket::VideoFormat format(
746 1280, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
Peter Boströmce23bee2016-02-02 14:14:30 +0100747 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700748 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], true, nullptr, &capturer));
Peter Boströmce23bee2016-02-02 14:14:30 +0100749 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format));
750 EXPECT_TRUE(capturer.CaptureFrame());
751
noahricfdac5162015-08-27 01:59:29 -0700752 ASSERT_EQ(1u, encoder_factory.encoders().size());
753 FakeWebRtcVideoEncoder* encoder = encoder_factory.encoders()[0];
pbos14fe7082016-04-20 06:35:56 -0700754 ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode());
noahricfdac5162015-08-27 01:59:29 -0700755 EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
756 EXPECT_EQ(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
deadbeef5a4a75a2016-06-02 16:23:38 -0700757 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], true, nullptr, nullptr));
noahricfdac5162015-08-27 01:59:29 -0700758}
759
brandtrffc61182016-11-28 06:02:22 -0800760// Test that the FlexFEC field trial properly alters the output of
761// WebRtcVideoEngine2::codecs(), for an existing |engine_| object.
762//
763// TODO(brandtr): Remove this test, when the FlexFEC field trial is gone.
764TEST_F(WebRtcVideoEngine2Test,
765 Flexfec03SupportedAsInternalCodecBehindFieldTrial) {
766 auto is_flexfec = [](const VideoCodec& codec) {
767 if (codec.name == "flexfec-03")
768 return true;
769 return false;
770 };
771
772 // FlexFEC is not active without field trial.
773 engine_.Init();
774 const std::vector<VideoCodec> codecs_before = engine_.codecs();
775 EXPECT_EQ(codecs_before.end(), std::find_if(codecs_before.begin(),
776 codecs_before.end(), is_flexfec));
777
778 // FlexFEC is active with field trial.
779 webrtc::test::ScopedFieldTrials override_field_trials_(
780 "WebRTC-FlexFEC-03/Enabled/");
781 const std::vector<VideoCodec> codecs_after = engine_.codecs();
782 EXPECT_NE(codecs_after.end(),
783 std::find_if(codecs_after.begin(), codecs_after.end(), is_flexfec));
784}
785
hbosbab934b2016-01-27 01:36:03 -0800786// Test that external codecs are added to the end of the supported codec list.
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000787TEST_F(WebRtcVideoEngine2Test, ReportSupportedExternalCodecs) {
788 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700789 encoder_factory.AddSupportedVideoCodecType("FakeExternalCodec");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000790 engine_.SetExternalEncoderFactory(&encoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200791 engine_.Init();
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000792
793 std::vector<cricket::VideoCodec> codecs(engine_.codecs());
794 ASSERT_GE(codecs.size(), 2u);
795 cricket::VideoCodec internal_codec = codecs.front();
796 cricket::VideoCodec external_codec = codecs.back();
797
brandtrffc61182016-11-28 06:02:22 -0800798 // The external codec will appear last in the vector.
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000799 EXPECT_EQ("VP8", internal_codec.name);
hbosbab934b2016-01-27 01:36:03 -0800800 EXPECT_EQ("FakeExternalCodec", external_codec.name);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000801}
802
brandtrffc61182016-11-28 06:02:22 -0800803// Test that an external codec that was added after the engine was initialized
804// does show up in the codec list after it was added.
805TEST_F(WebRtcVideoEngine2Test, ReportSupportedExternalCodecsWithAddedCodec) {
806 // Set up external encoder factory with first codec, and initialize engine.
807 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
808 encoder_factory.AddSupportedVideoCodecType("FakeExternalCodec1");
809 engine_.SetExternalEncoderFactory(&encoder_factory);
810 engine_.Init();
811
812 // The first external codec will appear last in the vector.
813 std::vector<cricket::VideoCodec> codecs_before(engine_.codecs());
814 EXPECT_EQ("FakeExternalCodec1", codecs_before.back().name);
815
816 // Add second codec.
817 encoder_factory.AddSupportedVideoCodecType("FakeExternalCodec2");
818 std::vector<cricket::VideoCodec> codecs_after(engine_.codecs());
819 EXPECT_EQ(codecs_before.size() + 1, codecs_after.size());
820 EXPECT_EQ("FakeExternalCodec2", codecs_after.back().name);
821}
822
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000823TEST_F(WebRtcVideoEngine2Test, RegisterExternalDecodersIfSupported) {
824 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
825 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200826 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800827 parameters.codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000828
kwiberg686a8ef2016-02-26 03:00:35 -0800829 std::unique_ptr<VideoMediaChannel> channel(
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200830 SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000831
832 EXPECT_TRUE(
833 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
834 ASSERT_EQ(1u, decoder_factory.decoders().size());
835
836 // Setting codecs of the same type should not reallocate the decoder.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200837 EXPECT_TRUE(channel->SetRecvParameters(parameters));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000838 EXPECT_EQ(1, decoder_factory.GetNumCreatedDecoders());
839
840 // Remove stream previously added to free the external decoder instance.
841 EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
842 EXPECT_EQ(0u, decoder_factory.decoders().size());
843}
844
845// Verifies that we can set up decoders that are not internally supported.
846TEST_F(WebRtcVideoEngine2Test, RegisterExternalH264DecoderIfSupported) {
847 // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We
848 // can't even query the WebRtcVideoDecoderFactory for supported codecs.
849 // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
850 // codecs.
851 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700852 encoder_factory.AddSupportedVideoCodecType("H264");
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000853 engine_.SetExternalEncoderFactory(&encoder_factory);
854 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
855 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264);
856 std::vector<cricket::VideoCodec> codecs;
magjed509e4fe2016-11-18 01:34:11 -0800857 codecs.push_back(GetEngineCodec("H264"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000858
kwiberg686a8ef2016-02-26 03:00:35 -0800859 std::unique_ptr<VideoMediaChannel> channel(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000860 SetUpForExternalDecoderFactory(&decoder_factory, codecs));
861
862 EXPECT_TRUE(
863 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
864 ASSERT_EQ(1u, decoder_factory.decoders().size());
865}
866
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000867class WebRtcVideoChannel2BaseTest
868 : public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> {
869 protected:
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000870 typedef VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> Base;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000871
magjed509e4fe2016-11-18 01:34:11 -0800872 cricket::VideoCodec GetEngineCodec(const std::string& name) {
873 for (const cricket::VideoCodec& engine_codec : engine_.codecs()) {
874 if (CodecNamesEq(name, engine_codec.name))
875 return engine_codec;
876 }
877 // This point should never be reached.
878 ADD_FAILURE() << "Unrecognized codec name: " << name;
879 return cricket::VideoCodec();
880 }
881
882 cricket::VideoCodec DefaultCodec() override { return GetEngineCodec("VP8"); }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000883};
884
sakal1fd95952016-06-22 00:46:15 -0700885// Verifies that id given in stream params is passed to the decoder factory.
886TEST_F(WebRtcVideoEngine2Test, StreamParamsIdPassedToDecoderFactory) {
887 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
888 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
889 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800890 parameters.codecs.push_back(GetEngineCodec("VP8"));
sakal1fd95952016-06-22 00:46:15 -0700891
892 std::unique_ptr<VideoMediaChannel> channel(
893 SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs));
894
895 StreamParams sp = cricket::StreamParams::CreateLegacy(kSsrc);
896 sp.id = "FakeStreamParamsId";
897 EXPECT_TRUE(channel->AddRecvStream(sp));
898 EXPECT_EQ(1u, decoder_factory.decoders().size());
899
900 std::vector<cricket::VideoDecoderParams> params = decoder_factory.params();
901 ASSERT_EQ(1u, params.size());
902 EXPECT_EQ(sp.id, params[0].receive_stream_id);
903}
904
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000905#define WEBRTC_BASE_TEST(test) \
906 TEST_F(WebRtcVideoChannel2BaseTest, test) { Base::test(); }
907
908#define WEBRTC_DISABLED_BASE_TEST(test) \
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000909 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_##test) { Base::test(); }
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000910
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000911WEBRTC_BASE_TEST(SetSend);
912WEBRTC_BASE_TEST(SetSendWithoutCodecs);
913WEBRTC_BASE_TEST(SetSendSetsTransportBufferSizes);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000914
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000915WEBRTC_BASE_TEST(GetStats);
916WEBRTC_BASE_TEST(GetStatsMultipleRecvStreams);
917WEBRTC_BASE_TEST(GetStatsMultipleSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000918
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000919WEBRTC_BASE_TEST(SetSendBandwidth);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000920
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000921WEBRTC_BASE_TEST(SetSendSsrc);
922WEBRTC_BASE_TEST(SetSendSsrcAfterSetCodecs);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000923
nisse08582ff2016-02-04 01:24:52 -0800924WEBRTC_BASE_TEST(SetSink);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000925
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000926WEBRTC_BASE_TEST(AddRemoveSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000927
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000928WEBRTC_BASE_TEST(SimulateConference);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000929
Alejandro Luebs947c02d2016-06-15 15:39:46 -0700930WEBRTC_DISABLED_BASE_TEST(AddRemoveCapturer);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000931
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000932WEBRTC_BASE_TEST(RemoveCapturerWithoutAdd);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000933
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000934WEBRTC_BASE_TEST(AddRemoveCapturerMultipleSources);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000935
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000936WEBRTC_BASE_TEST(RejectEmptyStreamParams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000937
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +0000938WEBRTC_BASE_TEST(MultipleSendStreams);
939
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000940TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Vga) {
magjed509e4fe2016-11-18 01:34:11 -0800941 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000942}
943
944TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Qvga) {
magjed509e4fe2016-11-18 01:34:11 -0800945 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000946}
947
948TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8SvcQqvga) {
magjed509e4fe2016-11-18 01:34:11 -0800949 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000950}
951
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000952TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) {
Peter Boströmd1f584b2016-04-20 16:31:53 +0200953 // Set a high bitrate to not be downscaled by VP8 due to low initial start
954 // bitrates. This currently happens at <250k, and two streams sharing 300k
955 // initially will use QVGA instead of VGA.
956 // TODO(pbos): Set up the quality scaler so that both senders reliably start
957 // at QVGA, then verify that instead.
magjed509e4fe2016-11-18 01:34:11 -0800958 cricket::VideoCodec codec = GetEngineCodec("VP8");
Peter Boströmd1f584b2016-04-20 16:31:53 +0200959 codec.params[kCodecParamStartBitrate] = "1000000";
960 Base::TwoStreamsSendAndReceive(codec);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000961}
962
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200963class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000964 public:
stefanc1aeaf02015-10-15 07:26:07 -0700965 WebRtcVideoChannel2Test() : WebRtcVideoChannel2Test("") {}
966 explicit WebRtcVideoChannel2Test(const char* field_trials)
967 : WebRtcVideoEngine2Test(field_trials), last_ssrc_(0) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000968 void SetUp() override {
skvlad11a9cbf2016-10-07 11:53:05 -0700969 fake_call_.reset(new FakeCall(webrtc::Call::Config(&event_log_)));
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200970 engine_.Init();
kthelgason83399ca2017-02-01 01:31:52 -0800971 channel_.reset(engine_.CreateChannel(fake_call_.get(), GetMediaConfig(),
972 VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -0800973 channel_->OnReadyToSend(true);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000974 last_ssrc_ = 123;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200975 send_parameters_.codecs = engine_.codecs();
976 recv_parameters_.codecs = engine_.codecs();
977 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000978 }
979
980 protected:
981 FakeVideoSendStream* AddSendStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000982 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000983 }
984
985 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000986 size_t num_streams = fake_call_->GetVideoSendStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000987 EXPECT_TRUE(channel_->AddSendStream(sp));
988 std::vector<FakeVideoSendStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000989 fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000990 EXPECT_EQ(num_streams + 1, streams.size());
991 return streams[streams.size() - 1];
992 }
993
994 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000995 return fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000996 }
997
998 FakeVideoReceiveStream* AddRecvStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000999 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001000 }
1001
1002 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001003 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001004 EXPECT_TRUE(channel_->AddRecvStream(sp));
1005 std::vector<FakeVideoReceiveStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001006 fake_call_->GetVideoReceiveStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001007 EXPECT_EQ(num_streams + 1, streams.size());
1008 return streams[streams.size() - 1];
1009 }
1010
pbos@webrtc.org00873182014-11-25 14:03:34 +00001011 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
1012 int expected_min_bitrate_bps,
1013 const char* start_bitrate_kbps,
1014 int expected_start_bitrate_bps,
1015 const char* max_bitrate_kbps,
1016 int expected_max_bitrate_bps) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001017 auto& codecs = send_parameters_.codecs;
1018 codecs.clear();
magjed509e4fe2016-11-18 01:34:11 -08001019 codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org00873182014-11-25 14:03:34 +00001020 codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps;
1021 codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps;
1022 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001023 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001024
pbos@webrtc.org00873182014-11-25 14:03:34 +00001025 EXPECT_EQ(expected_min_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +01001026 fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00001027 EXPECT_EQ(expected_start_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +01001028 fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00001029 EXPECT_EQ(expected_max_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +01001030 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001031 }
1032
isheriff6f8d6862016-05-26 11:24:55 -07001033 void TestSetSendRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001034 // Enable extension.
1035 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001036 cricket::VideoSendParameters parameters = send_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07001037 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001038 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001039 FakeVideoSendStream* send_stream =
1040 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1041
1042 // Verify the send extension id.
1043 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1044 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001045 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001046 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001047 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001048 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
1049 // receivers.
1050 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
1051 ->GetConfig()
1052 .rtp.extensions.empty());
1053
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001054 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001055 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001056 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1057 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001058 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
1059
1060 // Verify that adding receive RTP header extensions adds them for existing
1061 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001062 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001063 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001064 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1065 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001066 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001067 }
1068
isheriff6f8d6862016-05-26 11:24:55 -07001069 void TestSetRecvRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001070 // Enable extension.
1071 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001072 cricket::VideoRecvParameters parameters = recv_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07001073 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001074 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001075
1076 FakeVideoReceiveStream* recv_stream =
1077 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1078
1079 // Verify the recv extension id.
1080 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1081 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001082 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001083 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001084 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001085
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001086 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
1087 // senders.
1088 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
1089 ->GetConfig()
1090 .rtp.extensions.empty());
1091
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001092 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001093 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001094 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
1095 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001096 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
1097
1098 // Verify that adding receive RTP header extensions adds them for existing
1099 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001100 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001101 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001102 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1103 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001104 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001105 }
1106
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001107 void TestExtensionFilter(const std::vector<std::string>& extensions,
1108 const std::string& expected_extension) {
1109 cricket::VideoSendParameters parameters = send_parameters_;
1110 int expected_id = -1;
1111 int id = 1;
1112 for (const std::string& extension : extensions) {
1113 if (extension == expected_extension)
1114 expected_id = id;
isheriff6f8d6862016-05-26 11:24:55 -07001115 parameters.extensions.push_back(RtpExtension(extension, id++));
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001116 }
1117 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1118 FakeVideoSendStream* send_stream =
1119 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1120
1121 // Verify that only one of them has been set, and that it is the one with
1122 // highest priority (transport sequence number).
1123 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1124 EXPECT_EQ(expected_id, send_stream->GetConfig().rtp.extensions[0].id);
1125 EXPECT_EQ(expected_extension,
isheriff6f8d6862016-05-26 11:24:55 -07001126 send_stream->GetConfig().rtp.extensions[0].uri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001127 }
1128
Erik Språngefbde372015-04-29 16:21:28 +02001129 void TestCpuAdaptation(bool enable_overuse, bool is_screenshare);
Peter Boström3548dd22015-05-22 18:48:36 +02001130 void TestReceiverLocalSsrcConfiguration(bool receiver_first);
magjed509e4fe2016-11-18 01:34:11 -08001131 void TestReceiveUnsignaledSsrcPacket(uint8_t payload_type,
1132 bool expect_created_receive_stream);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001133
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001134 FakeVideoSendStream* SetDenoisingOption(
nisse05103312016-03-16 02:22:50 -07001135 uint32_t ssrc,
nisse0db023a2016-03-01 04:29:59 -08001136 cricket::FakeVideoCapturer* capturer,
1137 bool enabled) {
nisse05103312016-03-16 02:22:50 -07001138 cricket::VideoOptions options;
1139 options.video_noise_reduction = rtc::Optional<bool>(enabled);
deadbeef5a4a75a2016-06-02 16:23:38 -07001140 EXPECT_TRUE(channel_->SetVideoSend(ssrc, true, &options, capturer));
nisse0db023a2016-03-01 04:29:59 -08001141 // Options only take effect on the next frame.
1142 EXPECT_TRUE(capturer->CaptureFrame());
1143
Erik Språng143cec12015-04-28 10:01:41 +02001144 return fake_call_->GetVideoSendStreams().back();
1145 }
1146
Peter Boström2feafdb2015-09-09 14:32:14 +02001147 FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) {
1148 const int kRtxSsrcOffset = 0xDEADBEEF;
Erik Språng143cec12015-04-28 10:01:41 +02001149 last_ssrc_ += 3;
Peter Boström2feafdb2015-09-09 14:32:14 +02001150 std::vector<uint32_t> ssrcs;
1151 std::vector<uint32_t> rtx_ssrcs;
1152 uint32_t num_streams = enabled ? 3 : 1;
1153 for (uint32_t i = 0; i < num_streams; ++i) {
1154 uint32_t ssrc = last_ssrc_ + i;
1155 ssrcs.push_back(ssrc);
1156 if (with_rtx) {
1157 rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset);
1158 }
Erik Språng143cec12015-04-28 10:01:41 +02001159 }
Peter Boström2feafdb2015-09-09 14:32:14 +02001160 if (with_rtx) {
1161 return AddSendStream(
1162 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1163 }
1164 return AddSendStream(CreateSimStreamParams("cname", ssrcs));
Erik Språng143cec12015-04-28 10:01:41 +02001165 }
1166
perkjfa10b552016-10-02 23:45:26 -07001167 int GetMaxEncoderBitrate() {
skvladdc1c62c2016-03-16 19:07:43 -07001168 std::vector<FakeVideoSendStream*> streams =
1169 fake_call_->GetVideoSendStreams();
perkjfa10b552016-10-02 23:45:26 -07001170 EXPECT_EQ(1u, streams.size());
skvladdc1c62c2016-03-16 19:07:43 -07001171 FakeVideoSendStream* stream = streams[streams.size() - 1];
perkjfa10b552016-10-02 23:45:26 -07001172 EXPECT_EQ(1, stream->GetEncoderConfig().number_of_streams);
1173 return stream->GetVideoStreams()[0].max_bitrate_bps;
skvladdc1c62c2016-03-16 19:07:43 -07001174 }
1175
perkjfa10b552016-10-02 23:45:26 -07001176 void SetAndExpectMaxBitrate(int global_max,
skvladdc1c62c2016-03-16 19:07:43 -07001177 int stream_max,
1178 int expected_encoder_bitrate) {
1179 VideoSendParameters limited_send_params = send_parameters_;
1180 limited_send_params.max_bandwidth_bps = global_max;
1181 EXPECT_TRUE(channel_->SetSendParameters(limited_send_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001182 webrtc::RtpParameters parameters =
1183 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07001184 EXPECT_EQ(1UL, parameters.encodings.size());
1185 parameters.encodings[0].max_bitrate_bps = stream_max;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001186 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07001187 // Read back the parameteres and verify they have the correct value
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001188 parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07001189 EXPECT_EQ(1UL, parameters.encodings.size());
1190 EXPECT_EQ(stream_max, parameters.encodings[0].max_bitrate_bps);
1191 // Verify that the new value propagated down to the encoder
perkjfa10b552016-10-02 23:45:26 -07001192 EXPECT_EQ(expected_encoder_bitrate, GetMaxEncoderBitrate());
skvladdc1c62c2016-03-16 19:07:43 -07001193 }
1194
kwiberg686a8ef2016-02-26 03:00:35 -08001195 std::unique_ptr<FakeCall> fake_call_;
1196 std::unique_ptr<VideoMediaChannel> channel_;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001197 cricket::VideoSendParameters send_parameters_;
1198 cricket::VideoRecvParameters recv_parameters_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001199 uint32_t last_ssrc_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001200};
1201
pbos8fc7fa72015-07-15 08:02:58 -07001202TEST_F(WebRtcVideoChannel2Test, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02001203 const uint32_t kVideoSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07001204 const std::string kSyncLabel = "AvSyncLabel";
1205
1206 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc);
1207 sp.sync_label = kSyncLabel;
1208 EXPECT_TRUE(channel_->AddRecvStream(sp));
1209
1210 EXPECT_EQ(1, fake_call_->GetVideoReceiveStreams().size());
1211 EXPECT_EQ(kSyncLabel,
1212 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group)
1213 << "SyncGroup should be set based on sync_label";
1214}
1215
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001216TEST_F(WebRtcVideoChannel2Test, RecvStreamWithSimAndRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001217 cricket::VideoSendParameters parameters;
1218 parameters.codecs = engine_.codecs();
1219 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001220 EXPECT_TRUE(channel_->SetSend(true));
nisse4b4dc862016-02-17 05:25:36 -08001221 parameters.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001222 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001223
1224 // Send side.
Peter Boström0c4e06b2015-10-07 12:23:21 +02001225 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
1226 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001227 FakeVideoSendStream* send_stream = AddSendStream(
1228 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1229
1230 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
1231 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
1232 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
1233
1234 // Receiver side.
1235 FakeVideoReceiveStream* recv_stream = AddRecvStream(
1236 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
brandtr14742122017-01-27 04:53:07 -08001237 EXPECT_FALSE(recv_stream->GetConfig().rtp.rtx_payload_types.empty());
Peter Boströmd8b01092016-05-12 16:44:36 +02001238 EXPECT_EQ(recv_stream->GetConfig().decoders.size(),
brandtr14742122017-01-27 04:53:07 -08001239 recv_stream->GetConfig().rtp.rtx_payload_types.size())
Peter Boströmd8b01092016-05-12 16:44:36 +02001240 << "RTX should be mapped for all decoders/payload types.";
brandtr14742122017-01-27 04:53:07 -08001241 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001242}
1243
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001244TEST_F(WebRtcVideoChannel2Test, RecvStreamWithRtx) {
1245 // Setup one channel with an associated RTX stream.
1246 cricket::StreamParams params =
1247 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
1248 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
1249 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
brandtr14742122017-01-27 04:53:07 -08001250 EXPECT_EQ(kRtxSsrcs1[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001251}
1252
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001253TEST_F(WebRtcVideoChannel2Test, RecvStreamNoRtx) {
1254 // Setup one channel without an associated RTX stream.
1255 cricket::StreamParams params =
1256 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
1257 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
brandtr14742122017-01-27 04:53:07 -08001258 ASSERT_EQ(0U, recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001259}
1260
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001261TEST_F(WebRtcVideoChannel2Test, NoHeaderExtesionsByDefault) {
1262 FakeVideoSendStream* send_stream =
1263 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
1264 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
1265
1266 FakeVideoReceiveStream* recv_stream =
1267 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
1268 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001269}
1270
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001271// Test support for RTP timestamp offset header extension.
1272TEST_F(WebRtcVideoChannel2Test, SendRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001273 TestSetSendRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001274}
isheriff6f8d6862016-05-26 11:24:55 -07001275
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001276TEST_F(WebRtcVideoChannel2Test, RecvRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001277 TestSetRecvRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001278}
1279
1280// Test support for absolute send time header extension.
1281TEST_F(WebRtcVideoChannel2Test, SendAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001282 TestSetSendRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001283}
isheriff6f8d6862016-05-26 11:24:55 -07001284
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001285TEST_F(WebRtcVideoChannel2Test, RecvAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001286 TestSetRecvRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001287}
1288
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001289TEST_F(WebRtcVideoChannel2Test, FiltersExtensionsPicksTransportSeqNum) {
1290 // Enable three redundant extensions.
1291 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07001292 extensions.push_back(RtpExtension::kAbsSendTimeUri);
1293 extensions.push_back(RtpExtension::kTimestampOffsetUri);
1294 extensions.push_back(RtpExtension::kTransportSequenceNumberUri);
1295 TestExtensionFilter(extensions, RtpExtension::kTransportSequenceNumberUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001296}
1297
1298TEST_F(WebRtcVideoChannel2Test, FiltersExtensionsPicksAbsSendTime) {
1299 // Enable two redundant extensions.
1300 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07001301 extensions.push_back(RtpExtension::kAbsSendTimeUri);
1302 extensions.push_back(RtpExtension::kTimestampOffsetUri);
1303 TestExtensionFilter(extensions, RtpExtension::kAbsSendTimeUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001304}
1305
stefanc1aeaf02015-10-15 07:26:07 -07001306// Test support for transport sequence number header extension.
Stefan Holmer06a5e1a2016-09-02 12:36:49 +02001307TEST_F(WebRtcVideoChannel2Test, SendTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001308 TestSetSendRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07001309}
Stefan Holmer06a5e1a2016-09-02 12:36:49 +02001310TEST_F(WebRtcVideoChannel2Test, RecvTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001311 TestSetRecvRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07001312}
1313
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001314// Test support for video rotation header extension.
1315TEST_F(WebRtcVideoChannel2Test, SendVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001316 TestSetSendRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001317}
1318TEST_F(WebRtcVideoChannel2Test, RecvVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001319 TestSetRecvRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001320}
1321
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001322TEST_F(WebRtcVideoChannel2Test, IdenticalSendExtensionsDoesntRecreateStream) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001323 const int kAbsSendTimeId = 1;
1324 const int kVideoRotationId = 2;
isheriff6f8d6862016-05-26 11:24:55 -07001325 send_parameters_.extensions.push_back(
1326 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
1327 send_parameters_.extensions.push_back(
1328 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001329
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001330 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001331 FakeVideoSendStream* send_stream =
1332 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1333
1334 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001335 ASSERT_EQ(2u, send_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001336
1337 // Setting the same extensions (even if in different order) shouldn't
1338 // reallocate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001339 std::reverse(send_parameters_.extensions.begin(),
1340 send_parameters_.extensions.end());
1341 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001342
1343 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1344
1345 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001346 send_parameters_.extensions.resize(1);
1347 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001348
1349 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
1350}
1351
1352TEST_F(WebRtcVideoChannel2Test, IdenticalRecvExtensionsDoesntRecreateStream) {
1353 const int kTOffsetId = 1;
1354 const int kAbsSendTimeId = 2;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001355 const int kVideoRotationId = 3;
isheriff6f8d6862016-05-26 11:24:55 -07001356 recv_parameters_.extensions.push_back(
1357 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
1358 recv_parameters_.extensions.push_back(
1359 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
1360 recv_parameters_.extensions.push_back(
1361 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001362
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001363 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Peter Boström54be3e02015-05-25 15:04:24 +02001364 FakeVideoReceiveStream* recv_stream =
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001365 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1366
1367 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Peter Boström54be3e02015-05-25 15:04:24 +02001368 ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001369
1370 // Setting the same extensions (even if in different order) shouldn't
1371 // reallocate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001372 std::reverse(recv_parameters_.extensions.begin(),
1373 recv_parameters_.extensions.end());
1374 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001375
1376 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
1377
1378 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001379 recv_parameters_.extensions.resize(1);
1380 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001381
1382 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
1383}
1384
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001385TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001386 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001387 const int kUnsupportedId = 1;
1388 const int kTOffsetId = 2;
1389
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001390 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001391 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001392 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001393 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001394 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001395 FakeVideoSendStream* send_stream =
1396 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1397
1398 // Only timestamp offset extension is set to send stream,
1399 // unsupported rtp extension is ignored.
1400 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07001401 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
1402 send_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001403}
1404
1405TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001406 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001407 const int kUnsupportedId = 1;
1408 const int kTOffsetId = 2;
1409
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001410 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001411 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001412 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001413 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001414 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001415 FakeVideoReceiveStream* recv_stream =
1416 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1417
1418 // Only timestamp offset extension is set to receive stream,
1419 // unsupported rtp extension is ignored.
1420 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07001421 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
1422 recv_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001423}
1424
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001425TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02001426 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00001427 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07001428 send_parameters_.extensions.push_back(
1429 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001430 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001431 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1432 }
1433}
1434
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001435TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02001436 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00001437 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07001438 recv_parameters_.extensions.push_back(
1439 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001440 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001441 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1442 }
1443}
1444
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001445TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001446 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001447 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001448 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001449 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001450 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001451 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001452
1453 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001454 send_parameters_.extensions.clear();
1455 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001456 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001457 send_parameters_.extensions.push_back(send_parameters_.extensions.back());
1458 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001459}
1460
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001461TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001462 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001463 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001464 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001465 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001466 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001467 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001468
1469 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001470 recv_parameters_.extensions.clear();
1471 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001472 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001473 recv_parameters_.extensions.push_back(recv_parameters_.extensions.back());
1474 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001475}
1476
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001477TEST_F(WebRtcVideoChannel2Test, AddRecvStreamOnlyUsesOneReceiveStream) {
1478 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001479 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001480}
1481
Peter Boströmd7da1202015-06-05 14:09:38 +02001482TEST_F(WebRtcVideoChannel2Test, RtcpIsCompoundByDefault) {
1483 FakeVideoReceiveStream* stream = AddRecvStream();
pbosda903ea2015-10-02 02:36:56 -07001484 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream->GetConfig().rtp.rtcp_mode);
Peter Boströmd7da1202015-06-05 14:09:38 +02001485}
1486
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001487TEST_F(WebRtcVideoChannel2Test, RembIsEnabledByDefault) {
1488 FakeVideoReceiveStream* stream = AddRecvStream();
1489 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001490}
1491
stefan43edf0f2015-11-20 18:05:48 -08001492TEST_F(WebRtcVideoChannel2Test, TransportCcIsEnabledByDefault) {
1493 FakeVideoReceiveStream* stream = AddRecvStream();
1494 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1495}
1496
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001497TEST_F(WebRtcVideoChannel2Test, RembCanBeEnabledAndDisabled) {
1498 FakeVideoReceiveStream* stream = AddRecvStream();
1499 EXPECT_TRUE(stream->GetConfig().rtp.remb);
1500
Peter Boström126c03e2015-05-11 12:48:12 +02001501 // Verify that REMB is turned off when send(!) codecs without REMB are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001502 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001503 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001504 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1505 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001506 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001507 EXPECT_FALSE(stream->GetConfig().rtp.remb);
1508
1509 // Verify that REMB is turned on when setting default codecs since the
1510 // default codecs have REMB enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001511 parameters.codecs = engine_.codecs();
1512 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001513 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001514 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001515}
1516
stefan43edf0f2015-11-20 18:05:48 -08001517TEST_F(WebRtcVideoChannel2Test, TransportCcCanBeEnabledAndDisabled) {
1518 FakeVideoReceiveStream* stream = AddRecvStream();
1519 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1520
1521 // Verify that transport cc feedback is turned off when send(!) codecs without
1522 // transport cc feedback are set.
1523 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001524 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
stefan43edf0f2015-11-20 18:05:48 -08001525 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1526 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1527 stream = fake_call_->GetVideoReceiveStreams()[0];
1528 EXPECT_FALSE(stream->GetConfig().rtp.transport_cc);
1529
1530 // Verify that transport cc feedback is turned on when setting default codecs
1531 // since the default codecs have transport cc feedback enabled.
1532 parameters.codecs = engine_.codecs();
1533 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1534 stream = fake_call_->GetVideoReceiveStreams()[0];
1535 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1536}
1537
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001538TEST_F(WebRtcVideoChannel2Test, NackIsEnabledByDefault) {
1539 VerifyCodecHasDefaultFeedbackParams(default_codec_);
1540
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001541 cricket::VideoSendParameters parameters;
1542 parameters.codecs = engine_.codecs();
1543 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org19864742014-05-30 07:35:47 +00001544 EXPECT_TRUE(channel_->SetSend(true));
1545
1546 // Send side.
1547 FakeVideoSendStream* send_stream =
1548 AddSendStream(cricket::StreamParams::CreateLegacy(1));
1549 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1550
1551 // Receiver side.
1552 FakeVideoReceiveStream* recv_stream =
1553 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
1554 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1555
1556 // Nack history size should match between sender and receiver.
1557 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
1558 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001559}
1560
Peter Boström67c9df72015-05-11 14:34:58 +02001561TEST_F(WebRtcVideoChannel2Test, NackCanBeEnabledAndDisabled) {
Peter Boström67c9df72015-05-11 14:34:58 +02001562 FakeVideoSendStream* send_stream = AddSendStream();
Peter Boström3548dd22015-05-22 18:48:36 +02001563 FakeVideoReceiveStream* recv_stream = AddRecvStream();
Peter Boström67c9df72015-05-11 14:34:58 +02001564
1565 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1566 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1567
1568 // Verify that NACK is turned off when send(!) codecs without NACK are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001569 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001570 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001571 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1572 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02001573 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1574 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
1575 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001576 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
1577
Peter Boström67c9df72015-05-11 14:34:58 +02001578 // Verify that NACK is turned on when setting default codecs since the
1579 // default codecs have NACK enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001580 parameters.codecs = engine_.codecs();
1581 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02001582 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1583 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1584 send_stream = fake_call_->GetVideoSendStreams()[0];
1585 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001586}
1587
Peter Boströme7ba0862016-03-12 00:02:28 +01001588// This test verifies that new frame sizes reconfigures encoders even though not
1589// (yet) sending. The purpose of this is to permit encoding as quickly as
1590// possible once we start sending. Likely the frames being input are from the
1591// same source that will be sent later, which just means that we're ready
1592// earlier.
1593TEST_F(WebRtcVideoChannel2Test, ReconfiguresEncodersWhenNotSending) {
1594 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001595 parameters.codecs.push_back(GetEngineCodec("VP8"));
Peter Boströme7ba0862016-03-12 00:02:28 +01001596 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1597 channel_->SetSend(false);
1598
1599 FakeVideoSendStream* stream = AddSendStream();
1600
perkjfa10b552016-10-02 23:45:26 -07001601 // No frames entered.
Peter Boströme7ba0862016-03-12 00:02:28 +01001602 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07001603 EXPECT_EQ(0u, streams[0].width);
1604 EXPECT_EQ(0u, streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01001605
1606 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07001607 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
perkj26752742016-10-24 01:21:16 -07001608 VideoFormat capture_format = capturer.GetSupportedFormats()->front();
1609 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format));
Peter Boströme7ba0862016-03-12 00:02:28 +01001610 EXPECT_TRUE(capturer.CaptureFrame());
1611
1612 // Frame entered, should be reconfigured to new dimensions.
1613 streams = stream->GetVideoStreams();
perkj26752742016-10-24 01:21:16 -07001614 EXPECT_EQ(capture_format.width, streams[0].width);
1615 EXPECT_EQ(capture_format.height, streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01001616
deadbeef5a4a75a2016-06-02 16:23:38 -07001617 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boströme7ba0862016-03-12 00:02:28 +01001618}
1619
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001620TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) {
1621 static const int kScreenshareMinBitrateKbps = 800;
magjed509e4fe2016-11-18 01:34:11 -08001622 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001623 cricket::VideoSendParameters parameters;
1624 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001625 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001626 AddSendStream();
1627
deadbeef5a4a75a2016-06-02 16:23:38 -07001628 cricket::FakeVideoCapturer capturer;
nisse05103312016-03-16 02:22:50 -07001629 VideoOptions min_bitrate_options;
1630 min_bitrate_options.screencast_min_bitrate_kbps =
1631 rtc::Optional<int>(kScreenshareMinBitrateKbps);
deadbeef5a4a75a2016-06-02 16:23:38 -07001632 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &min_bitrate_options,
1633 &capturer));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001634 cricket::VideoFormat capture_format_hd =
1635 capturer.GetSupportedFormats()->front();
1636 EXPECT_EQ(1280, capture_format_hd.width);
1637 EXPECT_EQ(720, capture_format_hd.height);
1638 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1639
1640 EXPECT_TRUE(channel_->SetSend(true));
1641
1642 EXPECT_TRUE(capturer.CaptureFrame());
1643 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1644 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1645
1646 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1647
1648 // Verify non-screencast settings.
perkj26091b12016-09-01 01:17:40 -07001649 webrtc::VideoEncoderConfig encoder_config =
1650 send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02001651 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001652 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07001653 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
1654 EXPECT_EQ(capture_format_hd.width, streams.front().width);
1655 EXPECT_EQ(capture_format_hd.height, streams.front().height);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001656 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
1657 << "Non-screenshare shouldn't use min-transmit bitrate.";
1658
deadbeef5a4a75a2016-06-02 16:23:38 -07001659 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkjd533aec2017-01-13 05:57:25 -08001660 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
nisse05103312016-03-16 02:22:50 -07001661 VideoOptions screencast_options;
1662 screencast_options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001663 EXPECT_TRUE(
1664 channel_->SetVideoSend(last_ssrc_, true, &screencast_options, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08001665 EXPECT_TRUE(capturer.CaptureFrame());
Niels Möller60653ba2016-03-02 11:41:36 +01001666 // Send stream not recreated after option change.
1667 ASSERT_EQ(send_stream, fake_call_->GetVideoSendStreams().front());
perkjd533aec2017-01-13 05:57:25 -08001668 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001669
1670 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07001671 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02001672 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001673 encoder_config.content_type);
1674 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
1675 encoder_config.min_transmit_bitrate_bps);
1676
perkjfa10b552016-10-02 23:45:26 -07001677 streams = send_stream->GetVideoStreams();
1678 EXPECT_EQ(capture_format_hd.width, streams.front().width);
1679 EXPECT_EQ(capture_format_hd.height, streams.front().height);
1680 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
deadbeef5a4a75a2016-06-02 16:23:38 -07001681 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001682}
1683
Niels Möller60653ba2016-03-02 11:41:36 +01001684TEST_F(WebRtcVideoChannel2Test, NoRecreateStreamForScreencast) {
1685 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
1686 ASSERT_TRUE(
1687 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1688 EXPECT_TRUE(channel_->SetSend(true));
1689
1690 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07001691 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001692 EXPECT_EQ(cricket::CS_RUNNING,
1693 capturer.Start(capturer.GetSupportedFormats()->front()));
1694 EXPECT_TRUE(capturer.CaptureFrame());
1695
1696 ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1697 FakeVideoSendStream* stream = fake_call_->GetVideoSendStreams().front();
perkj26091b12016-09-01 01:17:40 -07001698 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
Niels Möller60653ba2016-03-02 11:41:36 +01001699 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
1700 encoder_config.content_type);
1701
1702 EXPECT_EQ(1, stream->GetNumberOfSwappedFrames());
1703
1704 /* Switch to screencast source. We expect a reconfigure of the
1705 * encoder, but no change of the send stream. */
1706 struct VideoOptions video_options;
1707 video_options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001708 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, &video_options, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001709
1710 EXPECT_TRUE(capturer.CaptureFrame());
1711 ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1712 ASSERT_EQ(stream, fake_call_->GetVideoSendStreams().front());
1713 EXPECT_EQ(2, stream->GetNumberOfSwappedFrames());
1714
perkj26091b12016-09-01 01:17:40 -07001715 encoder_config = stream->GetEncoderConfig().Copy();
Niels Möller60653ba2016-03-02 11:41:36 +01001716 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
1717 encoder_config.content_type);
1718
1719 /* Switch back. */
1720 video_options.is_screencast = rtc::Optional<bool>(false);
deadbeef5a4a75a2016-06-02 16:23:38 -07001721 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, &video_options, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001722
1723 EXPECT_TRUE(capturer.CaptureFrame());
1724 ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1725 ASSERT_EQ(stream, fake_call_->GetVideoSendStreams().front());
1726 EXPECT_EQ(3, stream->GetNumberOfSwappedFrames());
1727
perkj26091b12016-09-01 01:17:40 -07001728 encoder_config = stream->GetEncoderConfig().Copy();
Niels Möller60653ba2016-03-02 11:41:36 +01001729 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
1730 encoder_config.content_type);
1731
deadbeef5a4a75a2016-06-02 16:23:38 -07001732 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr, nullptr));
Niels Möller60653ba2016-03-02 11:41:36 +01001733}
1734
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001735TEST_F(WebRtcVideoChannel2Test,
1736 ConferenceModeScreencastConfiguresTemporalLayer) {
Erik Språng2c4c9142015-06-24 11:24:44 +02001737 static const int kConferenceScreencastTemporalBitrateBps =
1738 ScreenshareLayerConfig::GetDefault().tl0_bitrate_kbps * 1000;
nisse4b4dc862016-02-17 05:25:36 -08001739 send_parameters_.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001740 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001741
1742 AddSendStream();
nisse05103312016-03-16 02:22:50 -07001743 VideoOptions options;
1744 options.is_screencast = rtc::Optional<bool>(true);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001745 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07001746 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001747 cricket::VideoFormat capture_format_hd =
1748 capturer.GetSupportedFormats()->front();
1749 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1750
1751 EXPECT_TRUE(channel_->SetSend(true));
1752
1753 EXPECT_TRUE(capturer.CaptureFrame());
1754 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1755 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1756
perkj26091b12016-09-01 01:17:40 -07001757 webrtc::VideoEncoderConfig encoder_config =
1758 send_stream->GetEncoderConfig().Copy();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001759
1760 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07001761 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02001762 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001763 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07001764
1765 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
1766 ASSERT_EQ(1u, streams.size());
1767 ASSERT_EQ(1u, streams[0].temporal_layer_thresholds_bps.size());
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001768 EXPECT_EQ(kConferenceScreencastTemporalBitrateBps,
perkjfa10b552016-10-02 23:45:26 -07001769 streams[0].temporal_layer_thresholds_bps[0]);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001770
deadbeef5a4a75a2016-06-02 16:23:38 -07001771 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001772}
1773
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001774TEST_F(WebRtcVideoChannel2Test, SuspendBelowMinBitrateDisabledByDefault) {
1775 FakeVideoSendStream* stream = AddSendStream();
1776 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1777}
1778
nisse0db023a2016-03-01 04:29:59 -08001779TEST_F(WebRtcVideoChannel2Test, SetMediaConfigSuspendBelowMinBitrate) {
kthelgason83399ca2017-02-01 01:31:52 -08001780 MediaConfig media_config = GetMediaConfig();
nisse0db023a2016-03-01 04:29:59 -08001781 media_config.video.suspend_below_min_bitrate = true;
1782
1783 channel_.reset(
1784 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08001785 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08001786
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001787 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001788
1789 FakeVideoSendStream* stream = AddSendStream();
1790 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
1791
nisse0db023a2016-03-01 04:29:59 -08001792 media_config.video.suspend_below_min_bitrate = false;
1793 channel_.reset(
1794 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08001795 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08001796
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001797 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001798
nisse0db023a2016-03-01 04:29:59 -08001799 stream = AddSendStream();
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001800 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1801}
1802
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001803TEST_F(WebRtcVideoChannel2Test, Vp8DenoisingEnabledByDefault) {
1804 FakeVideoSendStream* stream = AddSendStream();
1805 webrtc::VideoCodecVP8 vp8_settings;
1806 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1807 EXPECT_TRUE(vp8_settings.denoisingOn);
1808}
1809
Erik Språng143cec12015-04-28 10:01:41 +02001810TEST_F(WebRtcVideoChannel2Test, VerifyVp8SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001811 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001812 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001813 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001814
Peter Boström2feafdb2015-09-09 14:32:14 +02001815 // Single-stream settings should apply with RTX as well (verifies that we
1816 // check number of regular SSRCs and not StreamParams::ssrcs which contains
1817 // both RTX and regular SSRCs).
1818 FakeVideoSendStream* stream = SetUpSimulcast(false, true);
Erik Språng143cec12015-04-28 10:01:41 +02001819
1820 cricket::FakeVideoCapturer capturer;
Erik Språng143cec12015-04-28 10:01:41 +02001821 EXPECT_EQ(cricket::CS_RUNNING,
1822 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07001823 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik Språng143cec12015-04-28 10:01:41 +02001824 channel_->SetSend(true);
1825
1826 EXPECT_TRUE(capturer.CaptureFrame());
1827
pbos4cba4eb2015-10-26 11:18:18 -07001828 webrtc::VideoCodecVP8 vp8_settings;
1829 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1830 EXPECT_TRUE(vp8_settings.denoisingOn)
1831 << "VP8 denoising should be on by default.";
1832
nisse05103312016-03-16 02:22:50 -07001833 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001834
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001835 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1836 EXPECT_FALSE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02001837 EXPECT_TRUE(vp8_settings.automaticResizeOn);
1838 EXPECT_TRUE(vp8_settings.frameDroppingOn);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001839
nisse05103312016-03-16 02:22:50 -07001840 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001841
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001842 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1843 EXPECT_TRUE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02001844 EXPECT_TRUE(vp8_settings.automaticResizeOn);
1845 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1846
deadbeef5a4a75a2016-06-02 16:23:38 -07001847 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boström2feafdb2015-09-09 14:32:14 +02001848 stream = SetUpSimulcast(true, false);
deadbeef5a4a75a2016-06-02 16:23:38 -07001849 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik Språng143cec12015-04-28 10:01:41 +02001850 channel_->SetSend(true);
1851 EXPECT_TRUE(capturer.CaptureFrame());
1852
1853 EXPECT_EQ(3, stream->GetVideoStreams().size());
1854 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1855 // Autmatic resize off when using simulcast.
1856 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1857 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1858
1859 // In screen-share mode, denoising is forced off and simulcast disabled.
nisse05103312016-03-16 02:22:50 -07001860 VideoOptions options;
1861 options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001862 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001863
nisse05103312016-03-16 02:22:50 -07001864 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001865
1866 EXPECT_EQ(1, stream->GetVideoStreams().size());
1867 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1868 EXPECT_FALSE(vp8_settings.denoisingOn);
1869 // Resizing and frame dropping always off for screen sharing.
1870 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1871 EXPECT_FALSE(vp8_settings.frameDroppingOn);
1872
nisse05103312016-03-16 02:22:50 -07001873 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
Erik Språng143cec12015-04-28 10:01:41 +02001874
1875 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1876 EXPECT_FALSE(vp8_settings.denoisingOn);
1877 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1878 EXPECT_FALSE(vp8_settings.frameDroppingOn);
1879
deadbeef5a4a75a2016-06-02 16:23:38 -07001880 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Erik Språng143cec12015-04-28 10:01:41 +02001881}
1882
deadbeef119760a2016-04-04 11:43:27 -07001883// Test that setting the same options doesn't result in the encoder being
1884// reconfigured.
1885TEST_F(WebRtcVideoChannel2Test, SetIdenticalOptionsDoesntReconfigureEncoder) {
1886 VideoOptions options;
1887 cricket::FakeVideoCapturer capturer;
1888
perkjfa10b552016-10-02 23:45:26 -07001889 AddSendStream();
deadbeef119760a2016-04-04 11:43:27 -07001890 EXPECT_EQ(cricket::CS_RUNNING,
1891 capturer.Start(capturer.GetSupportedFormats()->front()));
perkjfa10b552016-10-02 23:45:26 -07001892 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001893 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkjfa10b552016-10-02 23:45:26 -07001894 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1895 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1896
1897 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
deadbeef5a4a75a2016-06-02 16:23:38 -07001898 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
deadbeef119760a2016-04-04 11:43:27 -07001899 EXPECT_TRUE(capturer.CaptureFrame());
perkjfa10b552016-10-02 23:45:26 -07001900 // Expect 1 reconfigurations at this point from the initial configuration.
1901 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
deadbeef119760a2016-04-04 11:43:27 -07001902
1903 // Set the options one more time and expect no additional reconfigurations.
deadbeef5a4a75a2016-06-02 16:23:38 -07001904 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
perkjfa10b552016-10-02 23:45:26 -07001905 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
1906
1907 // Change |options| and expect 2 reconfigurations.
1908 options.is_screencast = rtc::Optional<bool>(true);
1909 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
deadbeef119760a2016-04-04 11:43:27 -07001910 EXPECT_EQ(2, send_stream->num_encoder_reconfigurations());
1911
deadbeef5a4a75a2016-06-02 16:23:38 -07001912 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
deadbeef119760a2016-04-04 11:43:27 -07001913}
1914
Erik Språng143cec12015-04-28 10:01:41 +02001915class Vp9SettingsTest : public WebRtcVideoChannel2Test {
1916 public:
asaperssonc5dabdd2016-03-21 04:15:50 -07001917 Vp9SettingsTest() : Vp9SettingsTest("") {}
1918 explicit Vp9SettingsTest(const char* field_trials)
1919 : WebRtcVideoChannel2Test(field_trials) {
magjed1e45cc62016-10-28 07:43:45 -07001920 encoder_factory_.AddSupportedVideoCodecType("VP9");
Erik Språng143cec12015-04-28 10:01:41 +02001921 }
1922 virtual ~Vp9SettingsTest() {}
1923
1924 protected:
1925 void SetUp() override {
1926 engine_.SetExternalEncoderFactory(&encoder_factory_);
1927
1928 WebRtcVideoChannel2Test::SetUp();
1929 }
1930
1931 void TearDown() override {
1932 // Remove references to encoder_factory_ since this will be destroyed
1933 // before channel_ and engine_.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001934 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
Erik Språng143cec12015-04-28 10:01:41 +02001935 }
1936
1937 cricket::FakeWebRtcVideoEncoderFactory encoder_factory_;
1938};
1939
1940TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001941 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001942 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001943 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Erik Språng143cec12015-04-28 10:01:41 +02001944
Peter Boström2feafdb2015-09-09 14:32:14 +02001945 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
Erik Språng143cec12015-04-28 10:01:41 +02001946
1947 cricket::FakeVideoCapturer capturer;
Erik Språng143cec12015-04-28 10:01:41 +02001948 EXPECT_EQ(cricket::CS_RUNNING,
1949 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07001950 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik Språng143cec12015-04-28 10:01:41 +02001951 channel_->SetSend(true);
1952
1953 EXPECT_TRUE(capturer.CaptureFrame());
1954
pbos4cba4eb2015-10-26 11:18:18 -07001955 webrtc::VideoCodecVP9 vp9_settings;
1956 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1957 EXPECT_FALSE(vp9_settings.denoisingOn)
1958 << "VP9 denoising should be off by default.";
1959
nisse05103312016-03-16 02:22:50 -07001960 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001961
Erik Språng143cec12015-04-28 10:01:41 +02001962 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1963 EXPECT_FALSE(vp9_settings.denoisingOn);
1964 // Frame dropping always on for real time video.
1965 EXPECT_TRUE(vp9_settings.frameDroppingOn);
1966
nisse05103312016-03-16 02:22:50 -07001967 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
Erik Språng143cec12015-04-28 10:01:41 +02001968
1969 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1970 EXPECT_TRUE(vp9_settings.denoisingOn);
1971 EXPECT_TRUE(vp9_settings.frameDroppingOn);
1972
1973 // In screen-share mode, denoising is forced off.
nisse05103312016-03-16 02:22:50 -07001974 VideoOptions options;
1975 options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001976 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08001977
nisse05103312016-03-16 02:22:50 -07001978 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001979
1980 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1981 EXPECT_FALSE(vp9_settings.denoisingOn);
1982 // Frame dropping always off for screen sharing.
1983 EXPECT_FALSE(vp9_settings.frameDroppingOn);
1984
nisse05103312016-03-16 02:22:50 -07001985 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001986
1987 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1988 EXPECT_FALSE(vp9_settings.denoisingOn);
1989 EXPECT_FALSE(vp9_settings.frameDroppingOn);
1990
deadbeef5a4a75a2016-06-02 16:23:38 -07001991 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001992}
1993
asaperssonc5dabdd2016-03-21 04:15:50 -07001994class Vp9SettingsTestWithFieldTrial : public Vp9SettingsTest {
1995 public:
brandtr468da7c2016-11-22 02:16:47 -08001996 explicit Vp9SettingsTestWithFieldTrial(const char* field_trials)
asaperssonc5dabdd2016-03-21 04:15:50 -07001997 : Vp9SettingsTest(field_trials) {}
1998
1999 protected:
2000 void VerifySettings(int num_spatial_layers, int num_temporal_layers) {
2001 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002002 parameters.codecs.push_back(GetEngineCodec("VP9"));
asaperssonc5dabdd2016-03-21 04:15:50 -07002003 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2004
2005 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
2006
2007 cricket::FakeVideoCapturer capturer;
2008 EXPECT_EQ(cricket::CS_RUNNING,
2009 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07002010 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
asaperssonc5dabdd2016-03-21 04:15:50 -07002011 channel_->SetSend(true);
2012
2013 EXPECT_TRUE(capturer.CaptureFrame());
2014
2015 webrtc::VideoCodecVP9 vp9_settings;
2016 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
2017 EXPECT_EQ(num_spatial_layers, vp9_settings.numberOfSpatialLayers);
2018 EXPECT_EQ(num_temporal_layers, vp9_settings.numberOfTemporalLayers);
2019
deadbeef5a4a75a2016-06-02 16:23:38 -07002020 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
asaperssonc5dabdd2016-03-21 04:15:50 -07002021 }
2022};
2023
2024class Vp9SettingsTestWithNoFlag : public Vp9SettingsTestWithFieldTrial {
2025 public:
2026 Vp9SettingsTestWithNoFlag() : Vp9SettingsTestWithFieldTrial("") {}
2027};
2028
2029TEST_F(Vp9SettingsTestWithNoFlag, VerifySettings) {
2030 const int kNumSpatialLayers = 1;
2031 const int kNumTemporalLayers = 1;
2032 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
2033}
2034
2035class Vp9SettingsTestWithInvalidFlag : public Vp9SettingsTestWithFieldTrial {
2036 public:
2037 Vp9SettingsTestWithInvalidFlag()
2038 : Vp9SettingsTestWithFieldTrial("WebRTC-SupportVP9SVC/Default/") {}
2039};
2040
2041TEST_F(Vp9SettingsTestWithInvalidFlag, VerifySettings) {
2042 const int kNumSpatialLayers = 1;
2043 const int kNumTemporalLayers = 1;
2044 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
2045}
2046
2047class Vp9SettingsTestWith2SL3TLFlag : public Vp9SettingsTestWithFieldTrial {
2048 public:
2049 Vp9SettingsTestWith2SL3TLFlag()
2050 : Vp9SettingsTestWithFieldTrial(
2051 "WebRTC-SupportVP9SVC/EnabledByFlag_2SL3TL/") {}
2052};
2053
2054TEST_F(Vp9SettingsTestWith2SL3TLFlag, VerifySettings) {
2055 const int kNumSpatialLayers = 2;
2056 const int kNumTemporalLayers = 3;
2057 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
2058}
2059
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002060TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruse) {
Erik Språngefbde372015-04-29 16:21:28 +02002061 TestCpuAdaptation(true, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002062}
2063
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002064TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenDisabled) {
Erik Språngefbde372015-04-29 16:21:28 +02002065 TestCpuAdaptation(false, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002066}
2067
Erik Språngefbde372015-04-29 16:21:28 +02002068TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenScreensharing) {
2069 TestCpuAdaptation(true, true);
2070}
2071
perkj2d5f0912016-02-29 00:04:41 -08002072TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruseAndChangeResolution) {
magjed509e4fe2016-11-18 01:34:11 -08002073 cricket::VideoCodec codec = GetEngineCodec("VP8");
perkj2d5f0912016-02-29 00:04:41 -08002074 cricket::VideoSendParameters parameters;
2075 parameters.codecs.push_back(codec);
2076
kthelgason83399ca2017-02-01 01:31:52 -08002077 MediaConfig media_config = GetMediaConfig();
perkj2d5f0912016-02-29 00:04:41 -08002078 channel_.reset(
2079 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002080 channel_->OnReadyToSend(true);
perkj2d5f0912016-02-29 00:04:41 -08002081 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2082
2083 AddSendStream();
2084
2085 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002086 ASSERT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08002087 ASSERT_EQ(cricket::CS_RUNNING,
2088 capturer.Start(capturer.GetSupportedFormats()->front()));
2089 ASSERT_TRUE(channel_->SetSend(true));
2090
2091 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2092 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
perkj2d5f0912016-02-29 00:04:41 -08002093
2094 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2095 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2096 EXPECT_EQ(1280, send_stream->GetLastWidth());
2097 EXPECT_EQ(720, send_stream->GetLastHeight());
2098
2099 // Trigger overuse.
perkj803d97f2016-11-01 11:45:46 -07002100 rtc::VideoSinkWants wants;
2101 wants.max_pixel_count = rtc::Optional<int>(
2102 send_stream->GetLastWidth() * send_stream->GetLastHeight() - 1);
2103 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002104 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2105 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
2106 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2107 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2108
2109 // Trigger overuse again.
perkj803d97f2016-11-01 11:45:46 -07002110 wants.max_pixel_count = rtc::Optional<int>(
2111 send_stream->GetLastWidth() * send_stream->GetLastHeight() - 1);
2112 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002113 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2114 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
2115 EXPECT_EQ(1280 * 2 / 4, send_stream->GetLastWidth());
2116 EXPECT_EQ(720 * 2 / 4, send_stream->GetLastHeight());
2117
2118 // Change input resolution.
2119 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
perkj803d97f2016-11-01 11:45:46 -07002120 EXPECT_EQ(4, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002121 EXPECT_EQ(1284 / 2, send_stream->GetLastWidth());
2122 EXPECT_EQ(724 / 2, send_stream->GetLastHeight());
2123
2124 // Trigger underuse which should go back up in resolution.
perkj803d97f2016-11-01 11:45:46 -07002125 wants.max_pixel_count = rtc::Optional<int>();
2126 wants.max_pixel_count_step_up = rtc::Optional<int>(
2127 send_stream->GetLastWidth() * send_stream->GetLastHeight());
2128 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002129 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
perkj803d97f2016-11-01 11:45:46 -07002130 EXPECT_EQ(5, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002131 EXPECT_EQ(1284 * 3 / 4, send_stream->GetLastWidth());
2132 EXPECT_EQ(724 * 3 / 4, send_stream->GetLastHeight());
2133
2134 // Trigger underuse which should go back up in resolution.
perkj803d97f2016-11-01 11:45:46 -07002135 wants.max_pixel_count = rtc::Optional<int>();
2136 wants.max_pixel_count_step_up = rtc::Optional<int>(
2137 send_stream->GetLastWidth() * send_stream->GetLastHeight());
2138 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002139 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
perkj803d97f2016-11-01 11:45:46 -07002140 EXPECT_EQ(6, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002141 EXPECT_EQ(1284, send_stream->GetLastWidth());
2142 EXPECT_EQ(724, send_stream->GetLastHeight());
2143
deadbeef5a4a75a2016-06-02 16:23:38 -07002144 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkj2d5f0912016-02-29 00:04:41 -08002145}
2146
Per766ad3b2016-04-05 15:23:49 +02002147TEST_F(WebRtcVideoChannel2Test, PreviousAdaptationDoesNotApplyToScreenshare) {
magjed509e4fe2016-11-18 01:34:11 -08002148 cricket::VideoCodec codec = GetEngineCodec("VP8");
Per766ad3b2016-04-05 15:23:49 +02002149 cricket::VideoSendParameters parameters;
2150 parameters.codecs.push_back(codec);
2151
kthelgason83399ca2017-02-01 01:31:52 -08002152 MediaConfig media_config = GetMediaConfig();
2153 media_config.video.enable_cpu_overuse_detection = true;
Per766ad3b2016-04-05 15:23:49 +02002154 channel_.reset(
2155 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002156 channel_->OnReadyToSend(true);
Per766ad3b2016-04-05 15:23:49 +02002157 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2158
2159 AddSendStream();
2160
2161 cricket::FakeVideoCapturer capturer;
Per766ad3b2016-04-05 15:23:49 +02002162 ASSERT_EQ(cricket::CS_RUNNING,
2163 capturer.Start(capturer.GetSupportedFormats()->front()));
2164 ASSERT_TRUE(channel_->SetSend(true));
2165 cricket::VideoOptions camera_options;
perkj803d97f2016-11-01 11:45:46 -07002166 camera_options.is_screencast = rtc::Optional<bool>(false);
deadbeef5a4a75a2016-06-02 16:23:38 -07002167 channel_->SetVideoSend(last_ssrc_, true /* enable */, &camera_options,
2168 &capturer);
Per766ad3b2016-04-05 15:23:49 +02002169
2170 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2171 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
Per766ad3b2016-04-05 15:23:49 +02002172
2173 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2174 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2175 EXPECT_EQ(1280, send_stream->GetLastWidth());
2176 EXPECT_EQ(720, send_stream->GetLastHeight());
2177
2178 // Trigger overuse.
perkj803d97f2016-11-01 11:45:46 -07002179 rtc::VideoSinkWants wants;
2180 wants.max_pixel_count = rtc::Optional<int>(
2181 send_stream->GetLastWidth() * send_stream->GetLastHeight() - 1);
2182 send_stream->InjectVideoSinkWants(wants);
Per766ad3b2016-04-05 15:23:49 +02002183 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2184 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
2185 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2186 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2187
2188 // Switch to screen share. Expect no CPU adaptation.
2189 cricket::FakeVideoCapturer screen_share(true);
2190 ASSERT_EQ(cricket::CS_RUNNING,
2191 screen_share.Start(screen_share.GetSupportedFormats()->front()));
Per766ad3b2016-04-05 15:23:49 +02002192 cricket::VideoOptions screenshare_options;
2193 screenshare_options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07002194 channel_->SetVideoSend(last_ssrc_, true /* enable */, &screenshare_options,
2195 &screen_share);
Per766ad3b2016-04-05 15:23:49 +02002196 EXPECT_TRUE(screen_share.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
2197 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
2198 EXPECT_EQ(1284, send_stream->GetLastWidth());
2199 EXPECT_EQ(724, send_stream->GetLastHeight());
2200
2201 // Switch back to the normal capturer. Expect the frame to be CPU adapted.
deadbeef5a4a75a2016-06-02 16:23:38 -07002202 channel_->SetVideoSend(last_ssrc_, true /* enable */, &camera_options,
2203 &capturer);
Per766ad3b2016-04-05 15:23:49 +02002204 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2205 EXPECT_EQ(4, send_stream->GetNumberOfSwappedFrames());
2206 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2207 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2208
deadbeef5a4a75a2016-06-02 16:23:38 -07002209 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Per766ad3b2016-04-05 15:23:49 +02002210}
2211
Erik Språngefbde372015-04-29 16:21:28 +02002212void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse,
2213 bool is_screenshare) {
magjed509e4fe2016-11-18 01:34:11 -08002214 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002215 cricket::VideoSendParameters parameters;
2216 parameters.codecs.push_back(codec);
nisse51542be2016-02-12 02:27:06 -08002217
kthelgason83399ca2017-02-01 01:31:52 -08002218 MediaConfig media_config = GetMediaConfig();
2219 if (enable_overuse) {
2220 media_config.video.enable_cpu_overuse_detection = true;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002221 }
nisse51542be2016-02-12 02:27:06 -08002222 channel_.reset(
2223 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002224 channel_->OnReadyToSend(true);
nisse51542be2016-02-12 02:27:06 -08002225
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002226 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002227
2228 AddSendStream();
2229
deadbeef5a4a75a2016-06-02 16:23:38 -07002230 cricket::FakeVideoCapturer capturer;
nisse05103312016-03-16 02:22:50 -07002231 VideoOptions options;
2232 options.is_screencast = rtc::Optional<bool>(is_screenshare);
deadbeef5a4a75a2016-06-02 16:23:38 -07002233 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
perkj26752742016-10-24 01:21:16 -07002234 cricket::VideoFormat capture_format = capturer.GetSupportedFormats()->front();
2235 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002236
2237 EXPECT_TRUE(channel_->SetSend(true));
2238
solenberge5269742015-09-08 05:13:22 -07002239 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
perkj2d5f0912016-02-29 00:04:41 -08002240
perkj803d97f2016-11-01 11:45:46 -07002241 if (!enable_overuse || is_screenshare) {
2242 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
perkj2d5f0912016-02-29 00:04:41 -08002243
2244 EXPECT_TRUE(capturer.CaptureFrame());
2245 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2246
perkj26752742016-10-24 01:21:16 -07002247 EXPECT_EQ(capture_format.width, send_stream->GetLastWidth());
2248 EXPECT_EQ(capture_format.height, send_stream->GetLastHeight());
perkj2d5f0912016-02-29 00:04:41 -08002249
deadbeef5a4a75a2016-06-02 16:23:38 -07002250 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkj2d5f0912016-02-29 00:04:41 -08002251 return;
2252 }
2253
perkj803d97f2016-11-01 11:45:46 -07002254 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
2255 // Trigger overuse.
2256 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2257
2258 rtc::VideoSinkWants wants;
2259 wants.max_pixel_count =
2260 rtc::Optional<int>(capture_format.width * capture_format.height - 1);
2261 send_stream->InjectVideoSinkWants(wants);
2262
perkj2d5f0912016-02-29 00:04:41 -08002263 EXPECT_TRUE(capturer.CaptureFrame());
2264 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002265
2266 EXPECT_TRUE(capturer.CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -08002267 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002268
perkj803d97f2016-11-01 11:45:46 -07002269 EXPECT_LT(send_stream->GetLastWidth(), capture_format.width);
2270 EXPECT_LT(send_stream->GetLastHeight(), capture_format.height);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002271
2272 // Trigger underuse which should go back to normal resolution.
perkj803d97f2016-11-01 11:45:46 -07002273 wants.max_pixel_count = rtc::Optional<int>();
2274 wants.max_pixel_count_step_up = rtc::Optional<int>(
2275 send_stream->GetLastWidth() * send_stream->GetLastHeight());
2276 send_stream->InjectVideoSinkWants(wants);
2277
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002278 EXPECT_TRUE(capturer.CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -08002279 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002280
perkj26752742016-10-24 01:21:16 -07002281 EXPECT_EQ(capture_format.width, send_stream->GetLastWidth());
2282 EXPECT_EQ(capture_format.height, send_stream->GetLastHeight());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002283
deadbeef5a4a75a2016-06-02 16:23:38 -07002284 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002285}
2286
magjedb09b6602015-10-01 03:02:44 -07002287TEST_F(WebRtcVideoChannel2Test, EstimatesNtpStartTimeCorrectly) {
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002288 // Start at last timestamp to verify that wraparounds are estimated correctly.
2289 static const uint32_t kInitialTimestamp = 0xFFFFFFFFu;
2290 static const int64_t kInitialNtpTimeMs = 1247891230;
2291 static const int kFrameOffsetMs = 20;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002292 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002293
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002294 FakeVideoReceiveStream* stream = AddRecvStream();
2295 cricket::FakeVideoRenderer renderer;
nisse08582ff2016-02-04 01:24:52 -08002296 EXPECT_TRUE(channel_->SetSink(last_ssrc_, &renderer));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002297
nisse64ec8f82016-09-27 00:17:25 -07002298 webrtc::VideoFrame video_frame(CreateBlackFrameBuffer(4, 4),
2299 kInitialTimestamp, 0,
2300 webrtc::kVideoRotation_0);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002301 // Initial NTP time is not available on the first frame, but should still be
2302 // able to be estimated.
nisseeb83a1a2016-03-21 01:27:56 -07002303 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002304
2305 EXPECT_EQ(1, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002306
2307 // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which
2308 // triggers a constant-overflow warning, hence we're calculating it explicitly
2309 // here.
2310 video_frame.set_timestamp(kFrameOffsetMs * 90 - 1);
2311 video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs);
nisseeb83a1a2016-03-21 01:27:56 -07002312 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002313
2314 EXPECT_EQ(2, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002315
2316 // Verify that NTP time has been correctly deduced.
2317 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002318 ASSERT_TRUE(channel_->GetStats(&info));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002319 ASSERT_EQ(1u, info.receivers.size());
2320 EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002321}
2322
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002323TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002324 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002325
2326 VideoCodec codec;
2327 EXPECT_TRUE(channel_->GetSendCodec(&codec));
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00002328 EXPECT_TRUE(codec.Matches(engine_.codecs()[0]));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002329
2330 // Using a RTX setup to verify that the default RTX payload type is good.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002331 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
2332 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002333 FakeVideoSendStream* stream = AddSendStream(
2334 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
perkj26091b12016-09-01 01:17:40 -07002335 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002336
2337 // Make sure NACK and FEC are enabled on the correct payload types.
2338 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
magjed509e4fe2016-11-18 01:34:11 -08002339 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
2340 EXPECT_EQ(GetEngineCodec("red").id, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002341
2342 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
2343 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
Shao Changbine62202f2015-04-21 20:24:50 +08002344 VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002345 // TODO(juberti): Check RTCP, PLI, TMMBR.
2346}
2347
brandtr468da7c2016-11-22 02:16:47 -08002348// TODO(brandtr): Remove when FlexFEC _is_ exposed by default.
2349TEST_F(WebRtcVideoChannel2Test, FlexfecCodecWithoutSsrcNotExposedByDefault) {
2350 FakeVideoSendStream* stream = AddSendStream();
2351 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2352
brandtr3d200bd2017-01-16 06:59:19 -08002353 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr468da7c2016-11-22 02:16:47 -08002354}
2355
2356// TODO(brandtr): Remove when FlexFEC _is_ exposed by default.
2357TEST_F(WebRtcVideoChannel2Test, FlexfecCodecWithSsrcNotExposedByDefault) {
2358 FakeVideoSendStream* stream = AddSendStream(
2359 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2360 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2361
brandtr3d200bd2017-01-16 06:59:19 -08002362 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr468da7c2016-11-22 02:16:47 -08002363}
2364
2365// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
2366// tests that use this test fixture into the corresponding "non-field trial"
2367// tests.
2368class WebRtcVideoChannel2FlexfecTest : public WebRtcVideoChannel2Test {
2369 public:
2370 WebRtcVideoChannel2FlexfecTest()
2371 : WebRtcVideoChannel2Test("WebRTC-FlexFEC-03/Enabled/") {}
2372};
2373
2374// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2375// by default.
brandtr36e7d702017-01-13 07:15:54 -08002376TEST_F(WebRtcVideoChannel2FlexfecTest,
2377 DefaultFlexfecCodecHasTransportCcAndRembFeedbackParam) {
2378 EXPECT_TRUE(cricket::HasTransportCc(GetEngineCodec("flexfec-03")));
2379 EXPECT_TRUE(cricket::HasRemb(GetEngineCodec("flexfec-03")));
2380}
2381
2382// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2383// by default.
brandtr468da7c2016-11-22 02:16:47 -08002384TEST_F(WebRtcVideoChannel2FlexfecTest, SetDefaultSendCodecsWithoutSsrc) {
2385 FakeVideoSendStream* stream = AddSendStream();
2386 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2387
brandtr3d200bd2017-01-16 06:59:19 -08002388 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
2389 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
2390 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
brandtr468da7c2016-11-22 02:16:47 -08002391}
2392
2393// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2394// by default.
2395TEST_F(WebRtcVideoChannel2FlexfecTest, SetDefaultSendCodecsWithSsrc) {
2396 FakeVideoSendStream* stream = AddSendStream(
2397 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2398 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2399
brandtr3d200bd2017-01-16 06:59:19 -08002400 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
2401 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
2402 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
2403 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08002404}
2405
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002406TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002407 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002408 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002409 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002410
2411 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07002412 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002413
brandtrb5f2c3f2016-10-04 23:28:39 -07002414 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type);
2415 EXPECT_EQ(-1, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002416}
2417
brandtr468da7c2016-11-22 02:16:47 -08002418// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2419// by default.
2420TEST_F(WebRtcVideoChannel2FlexfecTest, SetSendCodecsWithoutFec) {
2421 cricket::VideoSendParameters parameters;
2422 parameters.codecs.push_back(GetEngineCodec("VP8"));
2423 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2424
2425 FakeVideoSendStream* stream = AddSendStream();
2426 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2427
brandtr3d200bd2017-01-16 06:59:19 -08002428 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr468da7c2016-11-22 02:16:47 -08002429}
2430
brandtr9c3d4c42017-01-23 06:59:13 -08002431TEST_F(WebRtcVideoChannel2FlexfecTest, SetRecvCodecsWithFec) {
2432 AddRecvStream(
2433 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2434 const std::vector<FakeFlexfecReceiveStream*>& streams =
2435 fake_call_->GetFlexfecReceiveStreams();
2436
2437 cricket::VideoRecvParameters recv_parameters;
2438 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
2439 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2440 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
2441 ASSERT_EQ(1U, streams.size());
2442 const FakeFlexfecReceiveStream* stream_with_recv_params = streams.front();
2443 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
2444 stream_with_recv_params->GetConfig().payload_type);
2445 EXPECT_EQ(kFlexfecSsrc, stream_with_recv_params->GetConfig().remote_ssrc);
2446 EXPECT_EQ(1U,
2447 stream_with_recv_params->GetConfig().protected_media_ssrcs.size());
2448 EXPECT_EQ(kSsrcs1[0],
2449 stream_with_recv_params->GetConfig().protected_media_ssrcs[0]);
2450}
2451
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002452TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002453 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
magjed509e4fe2016-11-18 01:34:11 -08002454 const int kUnusedPayloadType = 127;
2455 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType));
2456
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002457 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002458 cricket::VideoCodec rtx_codec(kUnusedPayloadType, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002459 parameters.codecs.push_back(rtx_codec);
2460 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002461 << "RTX codec without associated payload type should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002462}
2463
2464TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002465 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
magjed509e4fe2016-11-18 01:34:11 -08002466 const int kUnusedPayloadType1 = 126;
2467 const int kUnusedPayloadType2 = 127;
2468 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
2469 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
2470 {
2471 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
2472 kUnusedPayloadType1, GetEngineCodec("VP8").id);
2473 cricket::VideoSendParameters parameters;
2474 parameters.codecs.push_back(GetEngineCodec("VP8"));
2475 parameters.codecs.push_back(rtx_codec);
2476 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2477 }
2478 {
2479 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
2480 kUnusedPayloadType1, kUnusedPayloadType2);
2481 cricket::VideoSendParameters parameters;
2482 parameters.codecs.push_back(GetEngineCodec("VP8"));
2483 parameters.codecs.push_back(rtx_codec);
2484 EXPECT_FALSE(channel_->SetSendParameters(parameters))
2485 << "RTX without matching video codec should be rejected.";
2486 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002487}
2488
brandtr14742122017-01-27 04:53:07 -08002489TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithChangedRtxPayloadType) {
2490 const int kUnusedPayloadType1 = 126;
2491 const int kUnusedPayloadType2 = 127;
2492 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
2493 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
2494
2495 // SSRCs for RTX.
2496 cricket::StreamParams params =
2497 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2498 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
2499 AddSendStream(params);
2500
2501 // Original payload type for RTX.
2502 cricket::VideoSendParameters parameters;
2503 parameters.codecs.push_back(GetEngineCodec("VP8"));
2504 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
2505 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
2506 parameters.codecs.push_back(rtx_codec);
2507 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2508 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
2509 const webrtc::VideoSendStream::Config& config_before =
2510 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2511 EXPECT_EQ(kUnusedPayloadType1, config_before.rtp.rtx.payload_type);
2512 ASSERT_EQ(1U, config_before.rtp.rtx.ssrcs.size());
2513 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx.ssrcs[0]);
2514
2515 // Change payload type for RTX.
2516 parameters.codecs[1].id = kUnusedPayloadType2;
2517 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2518 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
2519 const webrtc::VideoSendStream::Config& config_after =
2520 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2521 EXPECT_EQ(kUnusedPayloadType2, config_after.rtp.rtx.payload_type);
2522 ASSERT_EQ(1U, config_after.rtp.rtx.ssrcs.size());
2523 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx.ssrcs[0]);
2524}
2525
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002526TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002527 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002528 parameters.codecs.push_back(GetEngineCodec("VP8"));
2529 parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002530 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002531
2532 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07002533 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002534
magjed509e4fe2016-11-18 01:34:11 -08002535 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002536
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002537 parameters.codecs.pop_back();
2538 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002539 stream = fake_call_->GetVideoSendStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08002540 ASSERT_TRUE(stream != nullptr);
perkj26091b12016-09-01 01:17:40 -07002541 config = stream->GetConfig().Copy();
brandtrb5f2c3f2016-10-04 23:28:39 -07002542 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08002543 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
2544}
2545
2546// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2547// by default.
2548TEST_F(WebRtcVideoChannel2FlexfecTest, SetSendCodecsWithoutFecDisablesFec) {
2549 cricket::VideoSendParameters parameters;
2550 parameters.codecs.push_back(GetEngineCodec("VP8"));
2551 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2552 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2553
2554 FakeVideoSendStream* stream = AddSendStream(
2555 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2556 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2557
brandtr3d200bd2017-01-16 06:59:19 -08002558 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
2559 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
brandtr468da7c2016-11-22 02:16:47 -08002560 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
2561 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
2562
2563 parameters.codecs.pop_back();
2564 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2565 stream = fake_call_->GetVideoSendStreams()[0];
2566 ASSERT_TRUE(stream != nullptr);
2567 config = stream->GetConfig().Copy();
brandtr3d200bd2017-01-16 06:59:19 -08002568 EXPECT_EQ(-1, config.rtp.flexfec.payload_type)
brandtr468da7c2016-11-22 02:16:47 -08002569 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002570}
2571
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002572TEST_F(WebRtcVideoChannel2Test, SetSendCodecsChangesExistingStreams) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002573 cricket::VideoSendParameters parameters;
perkj26752742016-10-24 01:21:16 -07002574 cricket::VideoCodec codec(100, "VP8");
2575 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax);
2576 parameters.codecs.push_back(codec);
perkjfa10b552016-10-02 23:45:26 -07002577
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002578 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002579 channel_->SetSend(true);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002580
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002581 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002582 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002583 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002584
2585 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07002586 EXPECT_EQ(kDefaultQpMax, streams[0].max_qp);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002587
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002588 parameters.codecs.clear();
perkj26752742016-10-24 01:21:16 -07002589 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax + 1);
2590 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002591 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002592 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07002593 EXPECT_EQ(kDefaultQpMax + 1, streams[0].max_qp);
deadbeef5a4a75a2016-06-02 16:23:38 -07002594 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002595}
2596
pbos@webrtc.org00873182014-11-25 14:03:34 +00002597TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithBitrates) {
2598 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
2599 200000);
2600}
2601
pbos@webrtc.orga5f6fb52015-03-23 22:29:39 +00002602TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithHighMaxBitrate) {
2603 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
2604 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
2605 ASSERT_EQ(1u, streams.size());
2606 EXPECT_EQ(10000000, streams[0].max_bitrate_bps);
2607}
2608
pbos@webrtc.org00873182014-11-25 14:03:34 +00002609TEST_F(WebRtcVideoChannel2Test,
2610 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
2611 SetSendCodecsShouldWorkForBitrates(
2612 "", 0, "", -1, "", -1);
2613}
2614
2615TEST_F(WebRtcVideoChannel2Test, SetSendCodecsCapsMinAndStartBitrate) {
2616 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002617}
2618
2619TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectsMaxLessThanMinBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002620 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "300";
2621 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "200";
2622 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002623}
2624
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07002625// Test that when both the codec-specific bitrate params and max_bandwidth_bps
2626// are present in the same send parameters, the settings are combined correctly.
2627TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithBitratesAndMaxSendBandwidth) {
2628 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
2629 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
2630 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
2631 send_parameters_.max_bandwidth_bps = 400000;
2632 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2633 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2634 EXPECT_EQ(200000, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2635 // We expect max_bandwidth_bps to take priority, if set.
2636 EXPECT_EQ(400000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2637
2638 // Decrease max_bandwidth_bps.
2639 send_parameters_.max_bandwidth_bps = 350000;
2640 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2641 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2642 // Since the codec isn't changing, start_bitrate_bps should be -1.
2643 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2644 EXPECT_EQ(350000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2645
2646 // Now try again with the values flipped around.
2647 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
2648 send_parameters_.max_bandwidth_bps = 300000;
2649 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2650 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2651 EXPECT_EQ(200000, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2652 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2653
2654 // If we change the codec max, max_bandwidth_bps should still apply.
2655 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
2656 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2657 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2658 EXPECT_EQ(200000, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2659 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2660}
2661
pbos@webrtc.org00873182014-11-25 14:03:34 +00002662TEST_F(WebRtcVideoChannel2Test,
2663 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
2664 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
2665 200000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002666 send_parameters_.max_bandwidth_bps = 300000;
2667 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01002668 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002669 << "Setting max bitrate should keep previous min bitrate.";
Stefan Holmere5904162015-03-26 11:11:06 +01002670 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.start_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002671 << "Setting max bitrate should not reset start bitrate.";
Stefan Holmere5904162015-03-26 11:11:06 +01002672 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002673}
2674
2675TEST_F(WebRtcVideoChannel2Test, SetMaxSendBandwidthShouldBeRemovable) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002676 send_parameters_.max_bandwidth_bps = 300000;
2677 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01002678 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002679 // <= 0 means disable (infinite) max bitrate.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002680 send_parameters_.max_bandwidth_bps = 0;
2681 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01002682 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.max_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002683 << "Setting zero max bitrate did not reset start bitrate.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002684}
2685
perkjfa10b552016-10-02 23:45:26 -07002686TEST_F(WebRtcVideoChannel2Test, SetMaxSendBandwidthAndAddSendStream) {
2687 send_parameters_.max_bandwidth_bps = 99999;
2688 FakeVideoSendStream* stream = AddSendStream();
2689 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
2690 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
2691 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2692 ASSERT_EQ(1u, stream->GetVideoStreams().size());
2693 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
2694 stream->GetVideoStreams()[0].max_bitrate_bps);
2695
2696 send_parameters_.max_bandwidth_bps = 77777;
2697 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
2698 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
2699 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2700 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
2701 stream->GetVideoStreams()[0].max_bitrate_bps);
2702}
2703
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002704TEST_F(WebRtcVideoChannel2Test, SetMaxSendBitrateCanIncreaseSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002705 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002706 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002707 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002708 channel_->SetSend(true);
2709
2710 FakeVideoSendStream* stream = AddSendStream();
2711
Peter Boström3afc8c42016-01-27 16:45:21 +01002712 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002713 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Peter Boström3afc8c42016-01-27 16:45:21 +01002714 EXPECT_EQ(cricket::CS_RUNNING,
2715 capturer.Start(capturer.GetSupportedFormats()->front()));
2716
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002717 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
2718 int initial_max_bitrate_bps = streams[0].max_bitrate_bps;
2719 EXPECT_GT(initial_max_bitrate_bps, 0);
2720
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002721 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
2722 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01002723 // Insert a frame to update the encoder config.
2724 EXPECT_TRUE(capturer.CaptureFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002725 streams = stream->GetVideoStreams();
2726 EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps);
deadbeef5a4a75a2016-06-02 16:23:38 -07002727 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002728}
2729
2730TEST_F(WebRtcVideoChannel2Test,
2731 SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002732 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002733 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002734 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002735 channel_->SetSend(true);
2736
2737 FakeVideoSendStream* stream = AddSendStream(
2738 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
2739
2740 // Send a frame to make sure this scales up to >1 stream (simulcast).
2741 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002742 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], true, nullptr, &capturer));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002743 EXPECT_EQ(cricket::CS_RUNNING,
2744 capturer.Start(capturer.GetSupportedFormats()->front()));
2745 EXPECT_TRUE(capturer.CaptureFrame());
2746
2747 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
2748 ASSERT_GT(streams.size(), 1u)
2749 << "Without simulcast this test doesn't make sense.";
pbosbe16f792015-10-16 12:49:39 -07002750 int initial_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002751 EXPECT_GT(initial_max_bitrate_bps, 0);
2752
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002753 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
2754 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01002755 // Insert a frame to update the encoder config.
2756 EXPECT_TRUE(capturer.CaptureFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002757 streams = stream->GetVideoStreams();
pbosbe16f792015-10-16 12:49:39 -07002758 int increased_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002759 EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps);
2760
deadbeef5a4a75a2016-06-02 16:23:38 -07002761 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], true, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002762}
2763
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002764TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMaxQuantization) {
2765 static const char* kMaxQuantization = "21";
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002766 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002767 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002768 parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
2769 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00002770 EXPECT_EQ(static_cast<unsigned int>(atoi(kMaxQuantization)),
2771 AddSendStream()->GetVideoStreams().back().max_qp);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002772
2773 VideoCodec codec;
2774 EXPECT_TRUE(channel_->GetSendCodec(&codec));
2775 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
2776}
2777
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002778TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) {
2779 // TODO(pbos): Should we only allow the dynamic range?
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002780 static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002781 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002782 parameters.codecs.push_back(GetEngineCodec("VP8"));
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002783 for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002784 parameters.codecs[0].id = kIncorrectPayloads[i];
2785 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pkasting@chromium.orgd3245462015-02-23 21:28:22 +00002786 << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002787 }
2788}
2789
2790TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptAllValidPayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002791 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002792 parameters.codecs.push_back(GetEngineCodec("VP8"));
magjedf823ede2016-11-12 09:53:04 -08002793 for (int payload_type = 96; payload_type <= 127; ++payload_type) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002794 parameters.codecs[0].id = payload_type;
2795 EXPECT_TRUE(channel_->SetSendParameters(parameters))
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002796 << "Payload type '" << payload_type << "' rejected.";
2797 }
2798}
2799
deadbeef67cf2c12016-04-13 10:07:16 -07002800// Test that setting the a different set of codecs but with an identical front
2801// codec doesn't result in the stream being recreated.
2802// This may happen when a subsequent negotiation includes fewer codecs, as a
2803// result of one of the codecs being rejected.
2804TEST_F(WebRtcVideoChannel2Test,
2805 SetSendCodecsIdenticalFirstCodecDoesntRecreateStream) {
2806 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08002807 parameters1.codecs.push_back(GetEngineCodec("VP8"));
2808 parameters1.codecs.push_back(GetEngineCodec("VP9"));
deadbeef67cf2c12016-04-13 10:07:16 -07002809 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
2810
2811 AddSendStream();
2812 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2813
2814 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08002815 parameters2.codecs.push_back(GetEngineCodec("VP8"));
deadbeef67cf2c12016-04-13 10:07:16 -07002816 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
2817 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2818}
2819
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002820TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithOnlyVp8) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002821 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002822 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002823 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002824}
2825
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002826// Test that we set our inbound RTX codecs properly.
2827TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithRtx) {
magjed509e4fe2016-11-18 01:34:11 -08002828 const int kUnusedPayloadType1 = 126;
2829 const int kUnusedPayloadType2 = 127;
2830 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
2831 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
2832
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002833 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002834 parameters.codecs.push_back(GetEngineCodec("VP8"));
2835 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002836 parameters.codecs.push_back(rtx_codec);
2837 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002838 << "RTX codec without associated payload should be rejected.";
2839
magjed509e4fe2016-11-18 01:34:11 -08002840 parameters.codecs[1].SetParam("apt", kUnusedPayloadType2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002841 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002842 << "RTX codec with invalid associated payload type should be rejected.";
2843
magjed509e4fe2016-11-18 01:34:11 -08002844 parameters.codecs[1].SetParam("apt", GetEngineCodec("VP8").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002845 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002846
magjed509e4fe2016-11-18 01:34:11 -08002847 cricket::VideoCodec rtx_codec2(kUnusedPayloadType2, "rtx");
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002848 rtx_codec2.SetParam("apt", rtx_codec.id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002849 parameters.codecs.push_back(rtx_codec2);
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002850
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002851 EXPECT_FALSE(channel_->SetRecvParameters(parameters)) <<
2852 "RTX codec with another RTX as associated payload type should be "
2853 "rejected.";
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002854}
2855
brandtr14742122017-01-27 04:53:07 -08002856TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithChangedRtxPayloadType) {
2857 const int kUnusedPayloadType1 = 126;
2858 const int kUnusedPayloadType2 = 127;
2859 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
2860 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
2861
2862 // SSRCs for RTX.
2863 cricket::StreamParams params =
2864 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2865 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
2866 AddRecvStream(params);
2867
2868 // Original payload type for RTX.
2869 cricket::VideoRecvParameters parameters;
2870 parameters.codecs.push_back(GetEngineCodec("VP8"));
2871 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
2872 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
2873 parameters.codecs.push_back(rtx_codec);
2874 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2875 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
2876 const webrtc::VideoReceiveStream::Config& config_before =
2877 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
2878 EXPECT_EQ(1U, config_before.rtp.rtx_payload_types.size());
2879 auto it_before =
2880 config_before.rtp.rtx_payload_types.find(GetEngineCodec("VP8").id);
2881 ASSERT_NE(it_before, config_before.rtp.rtx_payload_types.end());
2882 EXPECT_EQ(kUnusedPayloadType1, it_before->second);
2883 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx_ssrc);
2884
2885 // Change payload type for RTX.
2886 parameters.codecs[1].id = kUnusedPayloadType2;
2887 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2888 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
2889 const webrtc::VideoReceiveStream::Config& config_after =
2890 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
2891 EXPECT_EQ(1U, config_after.rtp.rtx_payload_types.size());
2892 auto it_after =
2893 config_after.rtp.rtx_payload_types.find(GetEngineCodec("VP8").id);
2894 ASSERT_NE(it_after, config_after.rtp.rtx_payload_types.end());
2895 EXPECT_EQ(kUnusedPayloadType2, it_after->second);
2896 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx_ssrc);
2897}
2898
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002899TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentPayloadType) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002900 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002901 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002902 parameters.codecs[0].id = 99;
2903 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002904}
2905
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00002906TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsAcceptDefaultCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002907 cricket::VideoRecvParameters parameters;
2908 parameters.codecs = engine_.codecs();
2909 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00002910
2911 FakeVideoReceiveStream* stream = AddRecvStream();
Tommi733b5472016-06-10 17:58:01 +02002912 const webrtc::VideoReceiveStream::Config& config = stream->GetConfig();
pbos@webrtc.org776e6f22014-10-29 15:28:39 +00002913 EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].payload_name);
2914 EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002915}
2916
2917TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002918 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002919 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj26752742016-10-24 01:21:16 -07002920 parameters.codecs.push_back(VideoCodec(101, "WTF3"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002921 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002922}
2923
2924// TODO(pbos): Enable VP9 through external codec support
2925TEST_F(WebRtcVideoChannel2Test,
2926 DISABLED_SetRecvCodecsAcceptsMultipleVideoCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002927 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002928 parameters.codecs.push_back(GetEngineCodec("VP8"));
2929 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002930 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002931}
2932
2933TEST_F(WebRtcVideoChannel2Test,
2934 DISABLED_SetRecvCodecsSetsFecForAllVideoCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002935 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002936 parameters.codecs.push_back(GetEngineCodec("VP8"));
2937 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002938 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002939 FAIL(); // TODO(pbos): Verify that the FEC parameters are set for all codecs.
2940}
2941
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002942TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002943 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08002944 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
2945 send_parameters.codecs.push_back(GetEngineCodec("red"));
2946 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002947 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002948
2949 FakeVideoReceiveStream* stream = AddRecvStream();
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002950
magjed509e4fe2016-11-18 01:34:11 -08002951 EXPECT_EQ(GetEngineCodec("ulpfec").id,
brandtrb5f2c3f2016-10-04 23:28:39 -07002952 stream->GetConfig().rtp.ulpfec.ulpfec_payload_type);
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002953
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002954 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08002955 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002956 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002957 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08002958 ASSERT_TRUE(stream != nullptr);
brandtrb5f2c3f2016-10-04 23:28:39 -07002959 EXPECT_EQ(-1, stream->GetConfig().rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08002960 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
2961}
2962
2963// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2964// by default.
2965TEST_F(WebRtcVideoChannel2FlexfecTest, SetRecvParamsWithoutFecDisablesFec) {
2966 cricket::VideoSendParameters send_parameters;
2967 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
2968 send_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2969 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
2970
2971 AddRecvStream(
2972 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08002973 const std::vector<FakeFlexfecReceiveStream*>& streams =
brandtr468da7c2016-11-22 02:16:47 -08002974 fake_call_->GetFlexfecReceiveStreams();
2975
2976 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08002977 const FakeFlexfecReceiveStream* stream = streams.front();
2978 EXPECT_EQ(GetEngineCodec("flexfec-03").id, stream->GetConfig().payload_type);
2979 EXPECT_EQ(kFlexfecSsrc, stream->GetConfig().remote_ssrc);
2980 ASSERT_EQ(1U, stream->GetConfig().protected_media_ssrcs.size());
2981 EXPECT_EQ(kSsrcs1[0], stream->GetConfig().protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08002982
2983 cricket::VideoRecvParameters recv_parameters;
2984 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
2985 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
2986 EXPECT_TRUE(streams.empty())
2987 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002988}
2989
brandtre6f98c72016-11-11 03:28:30 -08002990TEST_F(WebRtcVideoChannel2Test, SetSendParamsWithFecEnablesFec) {
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002991 FakeVideoReceiveStream* stream = AddRecvStream();
magjed509e4fe2016-11-18 01:34:11 -08002992 EXPECT_EQ(GetEngineCodec("ulpfec").id,
brandtrb5f2c3f2016-10-04 23:28:39 -07002993 stream->GetConfig().rtp.ulpfec.ulpfec_payload_type);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002994
2995 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08002996 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
2997 recv_parameters.codecs.push_back(GetEngineCodec("red"));
2998 recv_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002999 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3000 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08003001 ASSERT_TRUE(stream != nullptr);
magjed509e4fe2016-11-18 01:34:11 -08003002 EXPECT_EQ(GetEngineCodec("ulpfec").id,
3003 stream->GetConfig().rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08003004 << "ULPFEC should be enabled on the receive stream.";
Stefan Holmer2b1f6512016-05-17 16:33:30 +02003005
3006 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08003007 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
3008 send_parameters.codecs.push_back(GetEngineCodec("red"));
3009 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02003010 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
3011 stream = fake_call_->GetVideoReceiveStreams()[0];
magjed509e4fe2016-11-18 01:34:11 -08003012 EXPECT_EQ(GetEngineCodec("ulpfec").id,
3013 stream->GetConfig().rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08003014 << "ULPFEC should be enabled on the receive stream.";
3015}
3016
3017// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
3018// by default.
3019TEST_F(WebRtcVideoChannel2FlexfecTest, SetSendParamsWithFecEnablesFec) {
3020 AddRecvStream(
3021 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08003022 const std::vector<FakeFlexfecReceiveStream*>& streams =
brandtr468da7c2016-11-22 02:16:47 -08003023 fake_call_->GetFlexfecReceiveStreams();
3024
3025 cricket::VideoRecvParameters recv_parameters;
3026 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3027 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3028 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3029 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08003030 const FakeFlexfecReceiveStream* stream_with_recv_params = streams.front();
brandtr468da7c2016-11-22 02:16:47 -08003031 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9c3d4c42017-01-23 06:59:13 -08003032 stream_with_recv_params->GetConfig().payload_type);
3033 EXPECT_EQ(kFlexfecSsrc, stream_with_recv_params->GetConfig().remote_ssrc);
brandtr468da7c2016-11-22 02:16:47 -08003034 EXPECT_EQ(1U,
brandtr9c3d4c42017-01-23 06:59:13 -08003035 stream_with_recv_params->GetConfig().protected_media_ssrcs.size());
brandtr468da7c2016-11-22 02:16:47 -08003036 EXPECT_EQ(kSsrcs1[0],
brandtr9c3d4c42017-01-23 06:59:13 -08003037 stream_with_recv_params->GetConfig().protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08003038
3039 cricket::VideoSendParameters send_parameters;
3040 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
3041 send_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3042 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
3043 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08003044 const FakeFlexfecReceiveStream* stream_with_send_params = streams.front();
brandtr468da7c2016-11-22 02:16:47 -08003045 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9c3d4c42017-01-23 06:59:13 -08003046 stream_with_send_params->GetConfig().payload_type);
3047 EXPECT_EQ(kFlexfecSsrc, stream_with_send_params->GetConfig().remote_ssrc);
brandtr468da7c2016-11-22 02:16:47 -08003048 EXPECT_EQ(1U,
brandtr9c3d4c42017-01-23 06:59:13 -08003049 stream_with_send_params->GetConfig().protected_media_ssrcs.size());
brandtr468da7c2016-11-22 02:16:47 -08003050 EXPECT_EQ(kSsrcs1[0],
brandtr9c3d4c42017-01-23 06:59:13 -08003051 stream_with_send_params->GetConfig().protected_media_ssrcs[0]);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02003052}
3053
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003054TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectDuplicateFecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003055 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003056 parameters.codecs.push_back(GetEngineCodec("VP8"));
3057 parameters.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003058 parameters.codecs[1].id = parameters.codecs[0].id;
3059 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003060}
3061
brandtr468da7c2016-11-22 02:16:47 -08003062// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
3063// by default.
3064TEST_F(WebRtcVideoChannel2FlexfecTest,
3065 SetSendCodecsRejectDuplicateFecPayloads) {
3066 cricket::VideoRecvParameters parameters;
3067 parameters.codecs.push_back(GetEngineCodec("VP8"));
3068 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3069 parameters.codecs[1].id = parameters.codecs[0].id;
3070 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
3071}
3072
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003073TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectDuplicateCodecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003074 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003075 parameters.codecs.push_back(GetEngineCodec("VP8"));
3076 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003077 parameters.codecs[1].id = parameters.codecs[0].id;
3078 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003079}
3080
3081TEST_F(WebRtcVideoChannel2Test,
3082 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003083 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003084 parameters.codecs.push_back(GetEngineCodec("VP8"));
3085 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003086 parameters.codecs[1].id += 1;
3087 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003088}
3089
deadbeef67cf2c12016-04-13 10:07:16 -07003090// Test that setting the same codecs but with a different order
deadbeef874ca3a2015-08-20 17:19:20 -07003091// doesn't result in the stream being recreated.
3092TEST_F(WebRtcVideoChannel2Test,
deadbeef67cf2c12016-04-13 10:07:16 -07003093 SetRecvCodecsDifferentOrderDoesntRecreateStream) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003094 cricket::VideoRecvParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08003095 parameters1.codecs.push_back(GetEngineCodec("VP8"));
3096 parameters1.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003097 EXPECT_TRUE(channel_->SetRecvParameters(parameters1));
deadbeef874ca3a2015-08-20 17:19:20 -07003098
3099 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
3100 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
3101
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003102 cricket::VideoRecvParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08003103 parameters2.codecs.push_back(GetEngineCodec("red"));
3104 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003105 EXPECT_TRUE(channel_->SetRecvParameters(parameters2));
deadbeef874ca3a2015-08-20 17:19:20 -07003106 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
3107}
3108
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003109TEST_F(WebRtcVideoChannel2Test, SendStreamNotSendingByDefault) {
3110 EXPECT_FALSE(AddSendStream()->IsSending());
3111}
3112
pbos@webrtc.org85f42942014-07-22 09:14:58 +00003113TEST_F(WebRtcVideoChannel2Test, ReceiveStreamReceivingByDefault) {
3114 EXPECT_TRUE(AddRecvStream()->IsReceiving());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003115}
3116
3117TEST_F(WebRtcVideoChannel2Test, SetSend) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +00003118 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003119 EXPECT_FALSE(stream->IsSending());
3120
3121 // false->true
3122 EXPECT_TRUE(channel_->SetSend(true));
3123 EXPECT_TRUE(stream->IsSending());
3124 // true->true
3125 EXPECT_TRUE(channel_->SetSend(true));
3126 EXPECT_TRUE(stream->IsSending());
3127 // true->false
3128 EXPECT_TRUE(channel_->SetSend(false));
3129 EXPECT_FALSE(stream->IsSending());
3130 // false->false
3131 EXPECT_TRUE(channel_->SetSend(false));
3132 EXPECT_FALSE(stream->IsSending());
3133
3134 EXPECT_TRUE(channel_->SetSend(true));
3135 FakeVideoSendStream* new_stream = AddSendStream();
3136 EXPECT_TRUE(new_stream->IsSending())
3137 << "Send stream created after SetSend(true) not sending initially.";
3138}
3139
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00003140// This test verifies DSCP settings are properly applied on video media channel.
3141TEST_F(WebRtcVideoChannel2Test, TestSetDscpOptions) {
kwiberg686a8ef2016-02-26 03:00:35 -08003142 std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00003143 new cricket::FakeNetworkInterface);
nisse51542be2016-02-12 02:27:06 -08003144 MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003145 std::unique_ptr<VideoMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003146
3147 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
3148 channel->SetInterface(network_interface.get());
3149 // Default value when DSCP is disabled should be DSCP_DEFAULT.
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00003150 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
nisse51542be2016-02-12 02:27:06 -08003151
3152 config.enable_dscp = true;
3153 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
3154 channel->SetInterface(network_interface.get());
3155 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
3156
3157 // Verify that setting the option to false resets the
3158 // DiffServCodePoint.
3159 config.enable_dscp = false;
3160 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
3161 channel->SetInterface(network_interface.get());
3162 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003163}
3164
deadbeef13871492015-12-09 12:37:51 -08003165// This test verifies that the RTCP reduced size mode is properly applied to
3166// send video streams.
3167TEST_F(WebRtcVideoChannel2Test, TestSetSendRtcpReducedSize) {
3168 // Create stream, expecting that default mode is "compound".
3169 FakeVideoSendStream* stream1 = AddSendStream();
3170 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
3171
3172 // Now enable reduced size mode.
3173 send_parameters_.rtcp.reduced_size = true;
3174 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3175 stream1 = fake_call_->GetVideoSendStreams()[0];
3176 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
3177
3178 // Create a new stream and ensure it picks up the reduced size mode.
3179 FakeVideoSendStream* stream2 = AddSendStream();
3180 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
3181}
3182
3183// This test verifies that the RTCP reduced size mode is properly applied to
3184// receive video streams.
3185TEST_F(WebRtcVideoChannel2Test, TestSetRecvRtcpReducedSize) {
3186 // Create stream, expecting that default mode is "compound".
3187 FakeVideoReceiveStream* stream1 = AddRecvStream();
3188 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
3189
3190 // Now enable reduced size mode.
Taylor Brandstetter5f0b83b2016-03-18 15:02:07 -07003191 // TODO(deadbeef): Once "recv_parameters" becomes "receiver_parameters",
3192 // the reduced_size flag should come from that.
3193 send_parameters_.rtcp.reduced_size = true;
3194 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
deadbeef13871492015-12-09 12:37:51 -08003195 stream1 = fake_call_->GetVideoReceiveStreams()[0];
3196 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
3197
3198 // Create a new stream and ensure it picks up the reduced size mode.
3199 FakeVideoReceiveStream* stream2 = AddRecvStream();
3200 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
3201}
3202
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003203TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) {
skvlad7a43d252016-03-22 15:32:27 -07003204 EXPECT_EQ(webrtc::kNetworkUp,
3205 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
3206 EXPECT_EQ(webrtc::kNetworkUp,
3207 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003208
3209 channel_->OnReadyToSend(false);
skvlad7a43d252016-03-22 15:32:27 -07003210 EXPECT_EQ(webrtc::kNetworkDown,
3211 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
3212 EXPECT_EQ(webrtc::kNetworkUp,
3213 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003214
3215 channel_->OnReadyToSend(true);
skvlad7a43d252016-03-22 15:32:27 -07003216 EXPECT_EQ(webrtc::kNetworkUp,
3217 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
3218 EXPECT_EQ(webrtc::kNetworkUp,
3219 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003220}
3221
Peter Boström74d9ed72015-03-26 16:28:31 +01003222TEST_F(WebRtcVideoChannel2Test, GetStatsReportsSentCodecName) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003223 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003224 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003225 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström74d9ed72015-03-26 16:28:31 +01003226
3227 AddSendStream();
3228
3229 cricket::VideoMediaInfo info;
3230 ASSERT_TRUE(channel_->GetStats(&info));
magjed509e4fe2016-11-18 01:34:11 -08003231 EXPECT_EQ("VP8", info.senders[0].codec_name);
Peter Boström74d9ed72015-03-26 16:28:31 +01003232}
3233
Peter Boströmb7d9a972015-12-18 16:01:11 +01003234TEST_F(WebRtcVideoChannel2Test, GetStatsReportsEncoderImplementationName) {
3235 FakeVideoSendStream* stream = AddSendStream();
3236 webrtc::VideoSendStream::Stats stats;
3237 stats.encoder_implementation_name = "encoder_implementation_name";
3238 stream->SetStats(stats);
3239
3240 cricket::VideoMediaInfo info;
3241 ASSERT_TRUE(channel_->GetStats(&info));
3242 EXPECT_EQ(stats.encoder_implementation_name,
3243 info.senders[0].encoder_implementation_name);
3244}
3245
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00003246TEST_F(WebRtcVideoChannel2Test, GetStatsReportsCpuOveruseMetrics) {
3247 FakeVideoSendStream* stream = AddSendStream();
3248 webrtc::VideoSendStream::Stats stats;
3249 stats.avg_encode_time_ms = 13;
3250 stats.encode_usage_percent = 42;
3251 stream->SetStats(stats);
3252
3253 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003254 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00003255 EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
3256 EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
3257}
3258
sakal43536c32016-10-24 01:46:43 -07003259TEST_F(WebRtcVideoChannel2Test, GetStatsReportsFramesEncoded) {
3260 FakeVideoSendStream* stream = AddSendStream();
3261 webrtc::VideoSendStream::Stats stats;
3262 stats.frames_encoded = 13;
3263 stream->SetStats(stats);
3264
3265 cricket::VideoMediaInfo info;
3266 ASSERT_TRUE(channel_->GetStats(&info));
3267 EXPECT_EQ(stats.frames_encoded, info.senders[0].frames_encoded);
3268}
3269
sakal87da4042016-10-31 06:53:47 -07003270TEST_F(WebRtcVideoChannel2Test, GetStatsReportsQpSum) {
3271 FakeVideoSendStream* stream = AddSendStream();
3272 webrtc::VideoSendStream::Stats stats;
3273 stats.qp_sum = rtc::Optional<uint64_t>(13);
3274 stream->SetStats(stats);
3275
3276 cricket::VideoMediaInfo info;
3277 ASSERT_TRUE(channel_->GetStats(&info));
3278 EXPECT_EQ(stats.qp_sum, info.senders[0].qp_sum);
3279}
3280
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003281TEST_F(WebRtcVideoChannel2Test, GetStatsReportsUpperResolution) {
3282 FakeVideoSendStream* stream = AddSendStream();
3283 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003284 stats.substreams[17].width = 123;
3285 stats.substreams[17].height = 40;
3286 stats.substreams[42].width = 80;
3287 stats.substreams[42].height = 31;
3288 stats.substreams[11].width = 20;
3289 stats.substreams[11].height = 90;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003290 stream->SetStats(stats);
3291
3292 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003293 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003294 ASSERT_EQ(1u, info.senders.size());
3295 EXPECT_EQ(123, info.senders[0].send_frame_width);
3296 EXPECT_EQ(90, info.senders[0].send_frame_height);
3297}
3298
Pera48ddb72016-09-29 11:48:50 +02003299TEST_F(WebRtcVideoChannel2Test, GetStatsReportsPreferredBitrate) {
3300 FakeVideoSendStream* stream = AddSendStream();
3301 webrtc::VideoSendStream::Stats stats;
3302 stats.preferred_media_bitrate_bps = 5;
3303 stream->SetStats(stats);
3304
3305 cricket::VideoMediaInfo info;
3306 ASSERT_TRUE(channel_->GetStats(&info));
3307 ASSERT_EQ(1u, info.senders.size());
3308 EXPECT_EQ(5, info.senders[0].preferred_bitrate);
3309}
3310
perkj803d97f2016-11-01 11:45:46 -07003311TEST_F(WebRtcVideoChannel2Test, GetStatsReportsCpuAdaptationStats) {
3312 FakeVideoSendStream* stream = AddSendStream();
3313 webrtc::VideoSendStream::Stats stats;
3314 stats.number_of_cpu_adapt_changes = 2;
3315 stats.cpu_limited_resolution = true;
3316 stream->SetStats(stats);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003317
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003318 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003319 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003320 ASSERT_EQ(1U, info.senders.size());
Per766ad3b2016-04-05 15:23:49 +02003321 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_CPU, info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07003322 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003323}
3324
perkj803d97f2016-11-01 11:45:46 -07003325TEST_F(WebRtcVideoChannel2Test, GetStatsReportsAdaptationAndBandwidthStats) {
3326 FakeVideoSendStream* stream = AddSendStream();
asapersson17821db2015-12-14 02:08:12 -08003327 webrtc::VideoSendStream::Stats stats;
perkj803d97f2016-11-01 11:45:46 -07003328 stats.number_of_cpu_adapt_changes = 2;
3329 stats.cpu_limited_resolution = true;
asapersson17821db2015-12-14 02:08:12 -08003330 stats.bw_limited_resolution = true;
perkj803d97f2016-11-01 11:45:46 -07003331 stream->SetStats(stats);
3332
3333 cricket::VideoMediaInfo info;
asapersson17821db2015-12-14 02:08:12 -08003334 EXPECT_TRUE(channel_->GetStats(&info));
3335 ASSERT_EQ(1U, info.senders.size());
Per766ad3b2016-04-05 15:23:49 +02003336 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_CPU |
3337 WebRtcVideoChannel2::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08003338 info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07003339 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
asapersson17821db2015-12-14 02:08:12 -08003340}
3341
3342TEST_F(WebRtcVideoChannel2Test,
3343 GetStatsTranslatesBandwidthLimitedResolutionCorrectly) {
3344 FakeVideoSendStream* stream = AddSendStream();
3345 webrtc::VideoSendStream::Stats stats;
3346 stats.bw_limited_resolution = true;
3347 stream->SetStats(stats);
3348
3349 cricket::VideoMediaInfo info;
3350 EXPECT_TRUE(channel_->GetStats(&info));
3351 ASSERT_EQ(1U, info.senders.size());
Per766ad3b2016-04-05 15:23:49 +02003352 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08003353 info.senders[0].adapt_reason);
3354}
3355
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003356TEST_F(WebRtcVideoChannel2Test,
3357 GetStatsTranslatesSendRtcpPacketTypesCorrectly) {
3358 FakeVideoSendStream* stream = AddSendStream();
3359 webrtc::VideoSendStream::Stats stats;
3360 stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2;
3361 stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3;
3362 stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4;
3363
3364 stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5;
3365 stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7;
3366 stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9;
3367
3368 stream->SetStats(stats);
3369
3370 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003371 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003372 EXPECT_EQ(7, info.senders[0].firs_rcvd);
3373 EXPECT_EQ(10, info.senders[0].nacks_rcvd);
3374 EXPECT_EQ(13, info.senders[0].plis_rcvd);
3375}
3376
3377TEST_F(WebRtcVideoChannel2Test,
3378 GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) {
3379 FakeVideoReceiveStream* stream = AddRecvStream();
3380 webrtc::VideoReceiveStream::Stats stats;
3381 stats.rtcp_packet_type_counts.fir_packets = 2;
3382 stats.rtcp_packet_type_counts.nack_packets = 3;
3383 stats.rtcp_packet_type_counts.pli_packets = 4;
3384 stream->SetStats(stats);
3385
3386 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003387 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003388 EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets,
3389 info.receivers[0].firs_sent);
3390 EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets,
3391 info.receivers[0].nacks_sent);
3392 EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets,
3393 info.receivers[0].plis_sent);
3394}
3395
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003396TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesDecodeStatsCorrectly) {
3397 FakeVideoReceiveStream* stream = AddRecvStream();
3398 webrtc::VideoReceiveStream::Stats stats;
Peter Boströmb7d9a972015-12-18 16:01:11 +01003399 stats.decoder_implementation_name = "decoder_implementation_name";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003400 stats.decode_ms = 2;
3401 stats.max_decode_ms = 3;
3402 stats.current_delay_ms = 4;
3403 stats.target_delay_ms = 5;
3404 stats.jitter_buffer_ms = 6;
3405 stats.min_playout_delay_ms = 7;
3406 stats.render_delay_ms = 8;
asapersson26dd92b2016-08-30 00:45:45 -07003407 stats.width = 9;
3408 stats.height = 10;
hbos42f6d2f2017-01-20 03:56:50 -08003409 stats.frame_counts.key_frames = 11;
3410 stats.frame_counts.delta_frames = 12;
hbos50cfe1f2017-01-23 07:21:55 -08003411 stats.frames_rendered = 13;
3412 stats.frames_decoded = 14;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003413 stream->SetStats(stats);
3414
3415 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003416 ASSERT_TRUE(channel_->GetStats(&info));
Peter Boströmb7d9a972015-12-18 16:01:11 +01003417 EXPECT_EQ(stats.decoder_implementation_name,
3418 info.receivers[0].decoder_implementation_name);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003419 EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
3420 EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
3421 EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
3422 EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
3423 EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
3424 EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
3425 EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
asapersson26dd92b2016-08-30 00:45:45 -07003426 EXPECT_EQ(stats.width, info.receivers[0].frame_width);
3427 EXPECT_EQ(stats.height, info.receivers[0].frame_height);
hbos42f6d2f2017-01-20 03:56:50 -08003428 EXPECT_EQ(stats.frame_counts.key_frames + stats.frame_counts.delta_frames,
3429 info.receivers[0].frames_received);
hbos50cfe1f2017-01-23 07:21:55 -08003430 EXPECT_EQ(stats.frames_rendered, info.receivers[0].frames_rendered);
sakale5ba44e2016-10-26 07:09:24 -07003431 EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003432}
3433
Peter Boström393347f2015-04-22 14:52:45 +02003434TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesReceivePacketStatsCorrectly) {
3435 FakeVideoReceiveStream* stream = AddRecvStream();
3436 webrtc::VideoReceiveStream::Stats stats;
3437 stats.rtp_stats.transmitted.payload_bytes = 2;
3438 stats.rtp_stats.transmitted.header_bytes = 3;
3439 stats.rtp_stats.transmitted.padding_bytes = 4;
3440 stats.rtp_stats.transmitted.packets = 5;
3441 stats.rtcp_stats.cumulative_lost = 6;
3442 stats.rtcp_stats.fraction_lost = 7;
3443 stream->SetStats(stats);
3444
3445 cricket::VideoMediaInfo info;
3446 ASSERT_TRUE(channel_->GetStats(&info));
3447 EXPECT_EQ(stats.rtp_stats.transmitted.payload_bytes +
3448 stats.rtp_stats.transmitted.header_bytes +
3449 stats.rtp_stats.transmitted.padding_bytes,
3450 info.receivers[0].bytes_rcvd);
3451 EXPECT_EQ(stats.rtp_stats.transmitted.packets,
3452 info.receivers[0].packets_rcvd);
3453 EXPECT_EQ(stats.rtcp_stats.cumulative_lost, info.receivers[0].packets_lost);
3454 EXPECT_EQ(static_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8),
3455 info.receivers[0].fraction_lost);
3456}
3457
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003458TEST_F(WebRtcVideoChannel2Test, TranslatesCallStatsCorrectly) {
3459 AddSendStream();
3460 AddSendStream();
3461 webrtc::Call::Stats stats;
3462 stats.rtt_ms = 123;
3463 fake_call_->SetStats(stats);
3464
3465 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003466 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003467 ASSERT_EQ(2u, info.senders.size());
3468 EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms);
3469 EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
3470}
3471
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003472TEST_F(WebRtcVideoChannel2Test, TranslatesSenderBitrateStatsCorrectly) {
3473 FakeVideoSendStream* stream = AddSendStream();
3474 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003475 stats.target_media_bitrate_bps = 156;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003476 stats.media_bitrate_bps = 123;
3477 stats.substreams[17].total_bitrate_bps = 1;
3478 stats.substreams[17].retransmit_bitrate_bps = 2;
3479 stats.substreams[42].total_bitrate_bps = 3;
3480 stats.substreams[42].retransmit_bitrate_bps = 4;
3481 stream->SetStats(stats);
3482
3483 FakeVideoSendStream* stream2 = AddSendStream();
3484 webrtc::VideoSendStream::Stats stats2;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003485 stats2.target_media_bitrate_bps = 200;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003486 stats2.media_bitrate_bps = 321;
3487 stats2.substreams[13].total_bitrate_bps = 5;
3488 stats2.substreams[13].retransmit_bitrate_bps = 6;
3489 stats2.substreams[21].total_bitrate_bps = 7;
3490 stats2.substreams[21].retransmit_bitrate_bps = 8;
3491 stream2->SetStats(stats2);
3492
3493 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003494 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003495 ASSERT_EQ(2u, info.senders.size());
3496 // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
3497 // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
3498 EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate);
3499 EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate);
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003500 EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
3501 info.bw_estimations[0].target_enc_bitrate);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003502 EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
3503 info.bw_estimations[0].actual_enc_bitrate);
3504 EXPECT_EQ(1 + 3 + 5 + 7, info.bw_estimations[0].transmit_bitrate)
3505 << "Bandwidth stats should take all streams into account.";
3506 EXPECT_EQ(2 + 4 + 6 + 8, info.bw_estimations[0].retransmit_bitrate)
3507 << "Bandwidth stats should take all streams into account.";
3508}
3509
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003510TEST_F(WebRtcVideoChannel2Test, DefaultReceiveStreamReconfiguresToUseRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003511 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003512
Peter Boström0c4e06b2015-10-07 12:23:21 +02003513 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3514 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003515
3516 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
3517 const size_t kDataLength = 12;
3518 uint8_t data[kDataLength];
3519 memset(data, 0, sizeof(data));
3520 rtc::SetBE32(&data[8], ssrcs[0]);
jbaucheec21bd2016-03-20 06:15:43 -07003521 rtc::CopyOnWriteBuffer packet(data, kDataLength);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003522 rtc::PacketTime packet_time;
3523 channel_->OnPacketReceived(&packet, packet_time);
3524
3525 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
3526 << "No default receive stream created.";
3527 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr14742122017-01-27 04:53:07 -08003528 EXPECT_EQ(0u, recv_stream->GetConfig().rtp.rtx_ssrc)
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003529 << "Default receive stream should not have configured RTX";
3530
3531 EXPECT_TRUE(channel_->AddRecvStream(
3532 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
3533 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
brandtr14742122017-01-27 04:53:07 -08003534 << "AddRecvStream should have reconfigured, not added a new receiver.";
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003535 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr14742122017-01-27 04:53:07 -08003536 EXPECT_FALSE(recv_stream->GetConfig().rtp.rtx_payload_types.empty());
Peter Boströmd8b01092016-05-12 16:44:36 +02003537 EXPECT_EQ(recv_stream->GetConfig().decoders.size(),
brandtr14742122017-01-27 04:53:07 -08003538 recv_stream->GetConfig().rtp.rtx_payload_types.size())
Peter Boströmd8b01092016-05-12 16:44:36 +02003539 << "RTX should be mapped for all decoders/payload types.";
brandtr14742122017-01-27 04:53:07 -08003540 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003541}
3542
Peter Boströmd4362cd2015-03-25 14:17:23 +01003543TEST_F(WebRtcVideoChannel2Test, RejectsAddingStreamsWithMissingSsrcsForRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003544 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd4362cd2015-03-25 14:17:23 +01003545
Peter Boström0c4e06b2015-10-07 12:23:21 +02003546 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3547 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd4362cd2015-03-25 14:17:23 +01003548
3549 StreamParams sp =
3550 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
3551 sp.ssrcs = ssrcs; // Without RTXs, this is the important part.
3552
3553 EXPECT_FALSE(channel_->AddSendStream(sp));
3554 EXPECT_FALSE(channel_->AddRecvStream(sp));
3555}
3556
Peter Boströmd6f4c252015-03-26 16:23:04 +01003557TEST_F(WebRtcVideoChannel2Test, RejectsAddingStreamsWithOverlappingRtxSsrcs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003558 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003559
Peter Boström0c4e06b2015-10-07 12:23:21 +02003560 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3561 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd6f4c252015-03-26 16:23:04 +01003562
3563 StreamParams sp =
3564 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
3565
3566 EXPECT_TRUE(channel_->AddSendStream(sp));
3567 EXPECT_TRUE(channel_->AddRecvStream(sp));
3568
3569 // The RTX SSRC is already used in previous streams, using it should fail.
3570 sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]);
3571 EXPECT_FALSE(channel_->AddSendStream(sp));
3572 EXPECT_FALSE(channel_->AddRecvStream(sp));
3573
3574 // After removing the original stream this should be fine to add (makes sure
3575 // that RTX ssrcs are not forever taken).
3576 EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0]));
3577 EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0]));
3578 EXPECT_TRUE(channel_->AddSendStream(sp));
3579 EXPECT_TRUE(channel_->AddRecvStream(sp));
3580}
3581
3582TEST_F(WebRtcVideoChannel2Test,
3583 RejectsAddingStreamsWithOverlappingSimulcastSsrcs) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003584 static const uint32_t kFirstStreamSsrcs[] = {1, 2, 3};
3585 static const uint32_t kOverlappingStreamSsrcs[] = {4, 3, 5};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003586 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003587
Peter Boströmd6f4c252015-03-26 16:23:04 +01003588 StreamParams sp =
3589 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs));
3590
3591 EXPECT_TRUE(channel_->AddSendStream(sp));
3592 EXPECT_TRUE(channel_->AddRecvStream(sp));
3593
3594 // One of the SSRCs is already used in previous streams, using it should fail.
3595 sp = cricket::CreateSimStreamParams("cname",
3596 MAKE_VECTOR(kOverlappingStreamSsrcs));
3597 EXPECT_FALSE(channel_->AddSendStream(sp));
3598 EXPECT_FALSE(channel_->AddRecvStream(sp));
3599
3600 // After removing the original stream this should be fine to add (makes sure
3601 // that RTX ssrcs are not forever taken).
Peter Boström3548dd22015-05-22 18:48:36 +02003602 EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0]));
3603 EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0]));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003604 EXPECT_TRUE(channel_->AddSendStream(sp));
3605 EXPECT_TRUE(channel_->AddRecvStream(sp));
3606}
3607
Peter Boström259bd202015-05-28 13:39:50 +02003608TEST_F(WebRtcVideoChannel2Test, ReportsSsrcGroupsInStats) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003609 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström259bd202015-05-28 13:39:50 +02003610
3611 static const uint32_t kSenderSsrcs[] = {4, 7, 10};
3612 static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11};
3613
3614 StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams(
3615 "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs));
3616
3617 EXPECT_TRUE(channel_->AddSendStream(sender_sp));
3618
3619 static const uint32_t kReceiverSsrcs[] = {3};
3620 static const uint32_t kReceiverRtxSsrcs[] = {2};
3621
3622 StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams(
3623 "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs));
3624 EXPECT_TRUE(channel_->AddRecvStream(receiver_sp));
3625
3626 cricket::VideoMediaInfo info;
3627 ASSERT_TRUE(channel_->GetStats(&info));
3628
3629 ASSERT_EQ(1u, info.senders.size());
3630 ASSERT_EQ(1u, info.receivers.size());
3631
3632 EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups);
3633 EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups);
3634 EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
3635}
3636
pbosf42376c2015-08-28 07:35:32 -07003637TEST_F(WebRtcVideoChannel2Test, MapsReceivedPayloadTypeToCodecName) {
3638 FakeVideoReceiveStream* stream = AddRecvStream();
3639 webrtc::VideoReceiveStream::Stats stats;
3640 cricket::VideoMediaInfo info;
3641
3642 // Report no codec name before receiving.
3643 stream->SetStats(stats);
3644 ASSERT_TRUE(channel_->GetStats(&info));
3645 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
3646
3647 // Report VP8 if we're receiving it.
magjed509e4fe2016-11-18 01:34:11 -08003648 stats.current_payload_type = GetEngineCodec("VP8").id;
pbosf42376c2015-08-28 07:35:32 -07003649 stream->SetStats(stats);
3650 ASSERT_TRUE(channel_->GetStats(&info));
3651 EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());
3652
3653 // Report no codec name for unknown playload types.
3654 stats.current_payload_type = 3;
3655 stream->SetStats(stats);
3656 ASSERT_TRUE(channel_->GetStats(&info));
3657 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
3658}
3659
magjed509e4fe2016-11-18 01:34:11 -08003660void WebRtcVideoChannel2Test::TestReceiveUnsignaledSsrcPacket(
noahricd10a68e2015-07-10 11:27:55 -07003661 uint8_t payload_type,
3662 bool expect_created_receive_stream) {
magjed509e4fe2016-11-18 01:34:11 -08003663 // kRedRtxPayloadType must currently be unused.
3664 EXPECT_FALSE(FindCodecById(engine_.codecs(), kRedRtxPayloadType));
3665
noahricd10a68e2015-07-10 11:27:55 -07003666 // Add a RED RTX codec.
3667 VideoCodec red_rtx_codec =
magjed509e4fe2016-11-18 01:34:11 -08003668 VideoCodec::CreateRtxCodec(kRedRtxPayloadType, GetEngineCodec("red").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003669 recv_parameters_.codecs.push_back(red_rtx_codec);
3670 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
noahricd10a68e2015-07-10 11:27:55 -07003671
3672 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
3673 const size_t kDataLength = 12;
3674 uint8_t data[kDataLength];
3675 memset(data, 0, sizeof(data));
3676
3677 rtc::Set8(data, 1, payload_type);
3678 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
jbaucheec21bd2016-03-20 06:15:43 -07003679 rtc::CopyOnWriteBuffer packet(data, kDataLength);
noahricd10a68e2015-07-10 11:27:55 -07003680 rtc::PacketTime packet_time;
3681 channel_->OnPacketReceived(&packet, packet_time);
3682
3683 if (expect_created_receive_stream) {
3684 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
3685 << "Should have created a receive stream for payload type: "
3686 << payload_type;
3687 } else {
3688 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size())
3689 << "Shouldn't have created a receive stream for payload type: "
3690 << payload_type;
3691 }
3692}
3693
3694TEST_F(WebRtcVideoChannel2Test, Vp8PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003695 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
3696 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003697}
3698
3699TEST_F(WebRtcVideoChannel2Test, Vp9PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003700 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP9").id,
3701 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003702}
3703
3704TEST_F(WebRtcVideoChannel2Test, RtxPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003705 const cricket::VideoCodec vp8 = GetEngineCodec("VP8");
3706 const int rtx_vp8_payload_type = default_apt_rtx_types_[vp8.id];
3707 TestReceiveUnsignaledSsrcPacket(rtx_vp8_payload_type,
3708 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003709}
3710
3711TEST_F(WebRtcVideoChannel2Test, UlpfecPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003712 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("ulpfec").id,
3713 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003714}
3715
brandtr468da7c2016-11-22 02:16:47 -08003716// TODO(brandtr): Change to "non-field trial" test when FlexFEC is enabled
3717// by default.
3718TEST_F(WebRtcVideoChannel2FlexfecTest,
3719 FlexfecPacketDoesntCreateUnsignalledStream) {
3720 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("flexfec-03").id,
3721 false /* expect_created_receive_stream */);
3722}
3723
noahricd10a68e2015-07-10 11:27:55 -07003724TEST_F(WebRtcVideoChannel2Test, RedRtxPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003725 TestReceiveUnsignaledSsrcPacket(kRedRtxPayloadType,
3726 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003727}
3728
skvladdc1c62c2016-03-16 19:07:43 -07003729TEST_F(WebRtcVideoChannel2Test, CanSentMaxBitrateForExistingStream) {
3730 AddSendStream();
3731
3732 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07003733 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
skvladdc1c62c2016-03-16 19:07:43 -07003734 cricket::VideoFormat capture_format_hd =
3735 capturer.GetSupportedFormats()->front();
3736 EXPECT_EQ(1280, capture_format_hd.width);
3737 EXPECT_EQ(720, capture_format_hd.height);
3738 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
3739 EXPECT_TRUE(channel_->SetSend(true));
perkjfa10b552016-10-02 23:45:26 -07003740 capturer.CaptureFrame();
skvladdc1c62c2016-03-16 19:07:43 -07003741
perkjfa10b552016-10-02 23:45:26 -07003742 int default_encoder_bitrate = GetMaxEncoderBitrate();
brandtr468da7c2016-11-22 02:16:47 -08003743 EXPECT_GT(default_encoder_bitrate, 1000);
skvladdc1c62c2016-03-16 19:07:43 -07003744
3745 // TODO(skvlad): Resolve the inconsistency between the interpretation
3746 // of the global bitrate limit for audio and video:
3747 // - Audio: max_bandwidth_bps = 0 - fail the operation,
3748 // max_bandwidth_bps = -1 - remove the bandwidth limit
3749 // - Video: max_bandwidth_bps = 0 - remove the bandwidth limit,
3750 // max_bandwidth_bps = -1 - do not change the previously set
3751 // limit.
3752
perkjfa10b552016-10-02 23:45:26 -07003753 SetAndExpectMaxBitrate(1000, 0, 1000);
3754 SetAndExpectMaxBitrate(1000, 800, 800);
3755 SetAndExpectMaxBitrate(600, 800, 600);
3756 SetAndExpectMaxBitrate(0, 800, 800);
3757 SetAndExpectMaxBitrate(0, 0, default_encoder_bitrate);
skvladdc1c62c2016-03-16 19:07:43 -07003758
deadbeef5a4a75a2016-06-02 16:23:38 -07003759 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
skvladdc1c62c2016-03-16 19:07:43 -07003760}
3761
3762TEST_F(WebRtcVideoChannel2Test, CannotSetMaxBitrateForNonexistentStream) {
3763 webrtc::RtpParameters nonexistent_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003764 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07003765 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
3766
3767 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003768 EXPECT_FALSE(
3769 channel_->SetRtpSendParameters(last_ssrc_, nonexistent_parameters));
skvladdc1c62c2016-03-16 19:07:43 -07003770}
3771
3772TEST_F(WebRtcVideoChannel2Test,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003773 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvladdc1c62c2016-03-16 19:07:43 -07003774 // This test verifies that setting RtpParameters succeeds only if
3775 // the structure contains exactly one encoding.
deadbeefdbe2b872016-03-22 15:42:00 -07003776 // TODO(skvlad): Update this test when we start supporting setting parameters
skvladdc1c62c2016-03-16 19:07:43 -07003777 // for each encoding individually.
3778
3779 AddSendStream();
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003780 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07003781 // Two or more encodings should result in failure.
3782 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003783 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08003784 // Zero encodings should also fail.
3785 parameters.encodings.clear();
3786 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
3787}
3788
3789// Changing the SSRC through RtpParameters is not allowed.
3790TEST_F(WebRtcVideoChannel2Test, CannotSetSsrcInRtpSendParameters) {
3791 AddSendStream();
3792 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
3793 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
3794 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07003795}
3796
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07003797// Test that a stream will not be sending if its encoding is made inactive
3798// through SetRtpSendParameters.
deadbeefdbe2b872016-03-22 15:42:00 -07003799// TODO(deadbeef): Update this test when we start supporting setting parameters
3800// for each encoding individually.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003801TEST_F(WebRtcVideoChannel2Test, SetRtpSendParametersEncodingsActive) {
deadbeefdbe2b872016-03-22 15:42:00 -07003802 FakeVideoSendStream* stream = AddSendStream();
3803 EXPECT_TRUE(channel_->SetSend(true));
3804 EXPECT_TRUE(stream->IsSending());
3805
3806 // Get current parameters and change "active" to false.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003807 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
deadbeefdbe2b872016-03-22 15:42:00 -07003808 ASSERT_EQ(1u, parameters.encodings.size());
3809 ASSERT_TRUE(parameters.encodings[0].active);
3810 parameters.encodings[0].active = false;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003811 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
deadbeefdbe2b872016-03-22 15:42:00 -07003812 EXPECT_FALSE(stream->IsSending());
3813
3814 // Now change it back to active and verify we resume sending.
3815 parameters.encodings[0].active = true;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003816 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
deadbeefdbe2b872016-03-22 15:42:00 -07003817 EXPECT_TRUE(stream->IsSending());
3818}
3819
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07003820// Test that if a stream is reconfigured (due to a codec change or other
3821// change) while its encoding is still inactive, it doesn't start sending.
3822TEST_F(WebRtcVideoChannel2Test,
3823 InactiveStreamDoesntStartSendingWhenReconfigured) {
3824 // Set an initial codec list, which will be modified later.
3825 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08003826 parameters1.codecs.push_back(GetEngineCodec("VP8"));
3827 parameters1.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07003828 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
3829
3830 FakeVideoSendStream* stream = AddSendStream();
3831 EXPECT_TRUE(channel_->SetSend(true));
3832 EXPECT_TRUE(stream->IsSending());
3833
3834 // Get current parameters and change "active" to false.
3835 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
3836 ASSERT_EQ(1u, parameters.encodings.size());
3837 ASSERT_TRUE(parameters.encodings[0].active);
3838 parameters.encodings[0].active = false;
3839 EXPECT_EQ(1u, GetFakeSendStreams().size());
3840 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
3841 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
3842 EXPECT_FALSE(stream->IsSending());
3843
3844 // Reorder the codec list, causing the stream to be reconfigured.
3845 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08003846 parameters2.codecs.push_back(GetEngineCodec("VP9"));
3847 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07003848 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
3849 auto new_streams = GetFakeSendStreams();
3850 // Assert that a new underlying stream was created due to the codec change.
3851 // Otherwise, this test isn't testing what it set out to test.
3852 EXPECT_EQ(1u, GetFakeSendStreams().size());
3853 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
3854
3855 // Verify that we still are not sending anything, due to the inactive
3856 // encoding.
3857 EXPECT_FALSE(new_streams[0]->IsSending());
3858}
3859
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003860// Test that GetRtpSendParameters returns the currently configured codecs.
3861TEST_F(WebRtcVideoChannel2Test, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003862 AddSendStream();
3863 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003864 parameters.codecs.push_back(GetEngineCodec("VP8"));
3865 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003866 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3867
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003868 webrtc::RtpParameters rtp_parameters =
3869 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003870 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08003871 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
3872 rtp_parameters.codecs[0]);
3873 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
3874 rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003875}
3876
deadbeeffb2aced2017-01-06 23:05:37 -08003877// Test that RtpParameters for send stream has one encoding and it has
3878// the correct SSRC.
3879TEST_F(WebRtcVideoChannel2Test, GetRtpSendParametersSsrc) {
3880 AddSendStream();
3881
3882 webrtc::RtpParameters rtp_parameters =
3883 channel_->GetRtpSendParameters(last_ssrc_);
3884 ASSERT_EQ(1u, rtp_parameters.encodings.size());
3885 EXPECT_EQ(rtc::Optional<uint32_t>(last_ssrc_),
3886 rtp_parameters.encodings[0].ssrc);
3887}
3888
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003889// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003890TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003891 AddSendStream();
3892 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003893 parameters.codecs.push_back(GetEngineCodec("VP8"));
3894 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003895 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3896
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003897 webrtc::RtpParameters initial_params =
3898 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003899
3900 // We should be able to set the params we just got.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003901 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003902
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003903 // ... And this shouldn't change the params returned by GetRtpSendParameters.
3904 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(last_ssrc_));
3905}
3906
3907// Test that GetRtpReceiveParameters returns the currently configured codecs.
3908TEST_F(WebRtcVideoChannel2Test, GetRtpReceiveParametersCodecs) {
3909 AddRecvStream();
3910 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003911 parameters.codecs.push_back(GetEngineCodec("VP8"));
3912 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003913 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
3914
3915 webrtc::RtpParameters rtp_parameters =
3916 channel_->GetRtpReceiveParameters(last_ssrc_);
3917 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08003918 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
3919 rtp_parameters.codecs[0]);
3920 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
3921 rtp_parameters.codecs[1]);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003922}
3923
johan073ece42016-08-26 02:59:47 -07003924#if defined(WEBRTC_USE_H264)
johan3859c892016-08-05 09:19:25 -07003925TEST_F(WebRtcVideoChannel2Test, GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07003926#else
3927TEST_F(WebRtcVideoChannel2Test, DISABLED_GetRtpReceiveFmtpSprop) {
3928#endif
johan3859c892016-08-05 09:19:25 -07003929 cricket::VideoRecvParameters parameters;
perkj26752742016-10-24 01:21:16 -07003930 cricket::VideoCodec kH264sprop1(101, "H264");
magjed5dfac562016-11-25 03:56:37 -08003931 kH264sprop1.SetParam(kH264FmtpSpropParameterSets, "uvw");
johan3859c892016-08-05 09:19:25 -07003932 parameters.codecs.push_back(kH264sprop1);
perkj26752742016-10-24 01:21:16 -07003933 cricket::VideoCodec kH264sprop2(102, "H264");
magjed5dfac562016-11-25 03:56:37 -08003934 kH264sprop2.SetParam(kH264FmtpSpropParameterSets, "xyz");
johan3859c892016-08-05 09:19:25 -07003935 parameters.codecs.push_back(kH264sprop2);
3936 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
3937
3938 FakeVideoReceiveStream* recv_stream = AddRecvStream();
3939 const webrtc::VideoReceiveStream::Config& cfg = recv_stream->GetConfig();
3940 webrtc::RtpParameters rtp_parameters =
3941 channel_->GetRtpReceiveParameters(last_ssrc_);
3942 ASSERT_EQ(2u, rtp_parameters.codecs.size());
3943 EXPECT_EQ(kH264sprop1.ToCodecParameters(), rtp_parameters.codecs[0]);
3944 ASSERT_EQ(2u, cfg.decoders.size());
3945 EXPECT_EQ(101, cfg.decoders[0].payload_type);
3946 EXPECT_EQ("H264", cfg.decoders[0].payload_name);
magjed5dfac562016-11-25 03:56:37 -08003947 const auto it0 =
3948 cfg.decoders[0].codec_params.find(kH264FmtpSpropParameterSets);
3949 ASSERT_TRUE(it0 != cfg.decoders[0].codec_params.end());
3950 EXPECT_EQ("uvw", it0->second);
johan3859c892016-08-05 09:19:25 -07003951
3952 EXPECT_EQ(102, cfg.decoders[1].payload_type);
3953 EXPECT_EQ("H264", cfg.decoders[1].payload_name);
magjed5dfac562016-11-25 03:56:37 -08003954 const auto it1 =
3955 cfg.decoders[1].codec_params.find(kH264FmtpSpropParameterSets);
3956 ASSERT_TRUE(it1 != cfg.decoders[1].codec_params.end());
3957 EXPECT_EQ("xyz", it1->second);
johan3859c892016-08-05 09:19:25 -07003958}
3959
sakal1fd95952016-06-22 00:46:15 -07003960// Test that RtpParameters for receive stream has one encoding and it has
3961// the correct SSRC.
deadbeeffb2aced2017-01-06 23:05:37 -08003962TEST_F(WebRtcVideoChannel2Test, GetRtpReceiveParametersSsrc) {
sakal1fd95952016-06-22 00:46:15 -07003963 AddRecvStream();
3964
3965 webrtc::RtpParameters rtp_parameters =
3966 channel_->GetRtpReceiveParameters(last_ssrc_);
3967 ASSERT_EQ(1u, rtp_parameters.encodings.size());
3968 EXPECT_EQ(rtc::Optional<uint32_t>(last_ssrc_),
3969 rtp_parameters.encodings[0].ssrc);
3970}
3971
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003972// Test that if we set/get parameters multiple times, we get the same results.
3973TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpReceiveParameters) {
3974 AddRecvStream();
3975 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003976 parameters.codecs.push_back(GetEngineCodec("VP8"));
3977 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003978 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
3979
3980 webrtc::RtpParameters initial_params =
3981 channel_->GetRtpReceiveParameters(last_ssrc_);
3982
3983 // We should be able to set the params we just got.
3984 EXPECT_TRUE(channel_->SetRtpReceiveParameters(last_ssrc_, initial_params));
3985
3986 // ... And this shouldn't change the params returned by
3987 // GetRtpReceiveParameters.
3988 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(last_ssrc_));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003989}
3990
Peter Boström3548dd22015-05-22 18:48:36 +02003991void WebRtcVideoChannel2Test::TestReceiverLocalSsrcConfiguration(
3992 bool receiver_first) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003993 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström3548dd22015-05-22 18:48:36 +02003994
3995 const uint32_t kSenderSsrc = 0xC0FFEE;
Peter Boströmdfa28152015-10-21 17:21:10 +02003996 const uint32_t kSecondSenderSsrc = 0xBADCAFE;
Peter Boström3548dd22015-05-22 18:48:36 +02003997 const uint32_t kReceiverSsrc = 0x4711;
Peter Boströmdfa28152015-10-21 17:21:10 +02003998 const uint32_t kExpectedDefaultReceiverSsrc = 1;
Peter Boström3548dd22015-05-22 18:48:36 +02003999
4000 if (receiver_first) {
4001 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
4002 std::vector<FakeVideoReceiveStream*> receive_streams =
4003 fake_call_->GetVideoReceiveStreams();
4004 ASSERT_EQ(1u, receive_streams.size());
Peter Boströmdfa28152015-10-21 17:21:10 +02004005 // Default local SSRC when we have no sender.
4006 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
4007 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02004008 }
4009 AddSendStream(StreamParams::CreateLegacy(kSenderSsrc));
4010 if (!receiver_first)
4011 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
4012 std::vector<FakeVideoReceiveStream*> receive_streams =
4013 fake_call_->GetVideoReceiveStreams();
4014 ASSERT_EQ(1u, receive_streams.size());
4015 EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boströmdfa28152015-10-21 17:21:10 +02004016
4017 // Removing first sender should fall back to another (in this case the second)
4018 // local send stream's SSRC.
4019 AddSendStream(StreamParams::CreateLegacy(kSecondSenderSsrc));
4020 ASSERT_TRUE(channel_->RemoveSendStream(kSenderSsrc));
4021 receive_streams =
4022 fake_call_->GetVideoReceiveStreams();
4023 ASSERT_EQ(1u, receive_streams.size());
4024 EXPECT_EQ(kSecondSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
4025
4026 // Removing the last sender should fall back to default local SSRC.
4027 ASSERT_TRUE(channel_->RemoveSendStream(kSecondSenderSsrc));
4028 receive_streams =
4029 fake_call_->GetVideoReceiveStreams();
4030 ASSERT_EQ(1u, receive_streams.size());
4031 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
4032 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02004033}
4034
4035TEST_F(WebRtcVideoChannel2Test, ConfiguresLocalSsrc) {
4036 TestReceiverLocalSsrcConfiguration(false);
4037}
4038
4039TEST_F(WebRtcVideoChannel2Test, ConfiguresLocalSsrcOnExistingReceivers) {
4040 TestReceiverLocalSsrcConfiguration(true);
4041}
4042
Fredrik Solenberg709ed672015-09-15 12:26:33 +02004043class WebRtcVideoChannel2SimulcastTest : public testing::Test {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004044 public:
skvlad11a9cbf2016-10-07 11:53:05 -07004045 WebRtcVideoChannel2SimulcastTest()
sprang429600d2017-01-26 06:12:26 -08004046 : fake_call_(webrtc::Call::Config(&event_log_)), last_ssrc_(0) {}
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004047
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00004048 void SetUp() override {
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +02004049 engine_.Init();
nisse51542be2016-02-12 02:27:06 -08004050 channel_.reset(
kthelgason83399ca2017-02-01 01:31:52 -08004051 engine_.CreateChannel(&fake_call_, GetMediaConfig(), VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08004052 channel_->OnReadyToSend(true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004053 last_ssrc_ = 123;
4054 }
4055
4056 protected:
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004057 void VerifySimulcastSettings(const VideoCodec& codec,
perkj26752742016-10-24 01:21:16 -07004058 int capture_width,
4059 int capture_height,
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004060 size_t num_configured_streams,
sprang429600d2017-01-26 06:12:26 -08004061 size_t expected_num_streams,
4062 bool screenshare,
4063 bool conference_mode) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004064 cricket::VideoSendParameters parameters;
sprang429600d2017-01-26 06:12:26 -08004065 VideoOptions options;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004066 parameters.codecs.push_back(codec);
sprang429600d2017-01-26 06:12:26 -08004067 parameters.conference_mode = conference_mode;
4068 if (screenshare) {
4069 options.is_screencast = rtc::Optional<bool>(screenshare);
4070 }
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004071 ASSERT_TRUE(channel_->SetSendParameters(parameters));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004072
Peter Boström0c4e06b2015-10-07 12:23:21 +02004073 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
henrikg91d6ede2015-09-17 00:24:34 -07004074 RTC_DCHECK(num_configured_streams <= ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004075 ssrcs.resize(num_configured_streams);
4076
4077 FakeVideoSendStream* stream =
4078 AddSendStream(CreateSimStreamParams("cname", ssrcs));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00004079 // Send a full-size frame to trigger a stream reconfiguration to use all
4080 // expected simulcast layers.
4081 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07004082 EXPECT_TRUE(
sprang429600d2017-01-26 06:12:26 -08004083 channel_->SetVideoSend(ssrcs.front(), true, &options, &capturer));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00004084 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(cricket::VideoFormat(
perkj26752742016-10-24 01:21:16 -07004085 capture_width, capture_height,
pbos@webrtc.org86196c42015-02-16 21:02:00 +00004086 cricket::VideoFormat::FpsToInterval(30),
4087 cricket::FOURCC_I420)));
4088 channel_->SetSend(true);
4089 EXPECT_TRUE(capturer.CaptureFrame());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004090
4091 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
4092 ASSERT_EQ(expected_num_streams, video_streams.size());
4093
sprang429600d2017-01-26 06:12:26 -08004094 std::vector<webrtc::VideoStream> expected_streams;
4095 if (conference_mode) {
4096 expected_streams = GetSimulcastConfig(
4097 num_configured_streams, capture_width, capture_height, 0,
4098 kDefaultQpMax, kDefaultVideoMaxFramerate, screenshare);
4099 } else {
4100 webrtc::VideoStream stream;
4101 stream.width = capture_width;
4102 stream.height = capture_height;
4103 stream.max_framerate = kDefaultVideoMaxFramerate;
4104 stream.min_bitrate_bps = cricket::kMinVideoBitrateKbps * 1000;
4105 int max_bitrate_kbps;
4106 if (capture_width * capture_height <= 320 * 240) {
4107 max_bitrate_kbps = 600;
4108 } else if (capture_width * capture_height <= 640 * 480) {
4109 max_bitrate_kbps = 1700;
4110 } else if (capture_width * capture_height <= 960 * 540) {
4111 max_bitrate_kbps = 2000;
4112 } else {
4113 max_bitrate_kbps = 2500;
4114 }
4115 stream.target_bitrate_bps = stream.max_bitrate_bps =
4116 max_bitrate_kbps * 1000;
4117 stream.max_qp = kDefaultQpMax;
4118 expected_streams.push_back(stream);
4119 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004120
4121 ASSERT_EQ(expected_streams.size(), video_streams.size());
4122
4123 size_t num_streams = video_streams.size();
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004124 int total_max_bitrate_bps = 0;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004125 for (size_t i = 0; i < num_streams; ++i) {
4126 EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
4127 EXPECT_EQ(expected_streams[i].height, video_streams[i].height);
4128
4129 EXPECT_GT(video_streams[i].max_framerate, 0);
4130 EXPECT_EQ(expected_streams[i].max_framerate,
4131 video_streams[i].max_framerate);
4132
4133 EXPECT_GT(video_streams[i].min_bitrate_bps, 0);
4134 EXPECT_EQ(expected_streams[i].min_bitrate_bps,
4135 video_streams[i].min_bitrate_bps);
4136
4137 EXPECT_GT(video_streams[i].target_bitrate_bps, 0);
4138 EXPECT_EQ(expected_streams[i].target_bitrate_bps,
4139 video_streams[i].target_bitrate_bps);
4140
4141 EXPECT_GT(video_streams[i].max_bitrate_bps, 0);
4142 EXPECT_EQ(expected_streams[i].max_bitrate_bps,
4143 video_streams[i].max_bitrate_bps);
4144
4145 EXPECT_GT(video_streams[i].max_qp, 0);
4146 EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp);
4147
sprang429600d2017-01-26 06:12:26 -08004148 EXPECT_EQ(!conference_mode,
4149 expected_streams[i].temporal_layer_thresholds_bps.empty());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004150 EXPECT_EQ(expected_streams[i].temporal_layer_thresholds_bps,
4151 video_streams[i].temporal_layer_thresholds_bps);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004152
4153 if (i == num_streams - 1) {
4154 total_max_bitrate_bps += video_streams[i].max_bitrate_bps;
4155 } else {
4156 total_max_bitrate_bps += video_streams[i].target_bitrate_bps;
4157 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004158 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004159
deadbeef5a4a75a2016-06-02 16:23:38 -07004160 EXPECT_TRUE(channel_->SetVideoSend(ssrcs.front(), true, nullptr, nullptr));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004161 }
4162
4163 FakeVideoSendStream* AddSendStream() {
4164 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++));
4165 }
4166
4167 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
4168 size_t num_streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02004169 fake_call_.GetVideoSendStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004170 EXPECT_TRUE(channel_->AddSendStream(sp));
4171 std::vector<FakeVideoSendStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02004172 fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004173 EXPECT_EQ(num_streams + 1, streams.size());
4174 return streams[streams.size() - 1];
4175 }
4176
4177 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02004178 return fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004179 }
4180
4181 FakeVideoReceiveStream* AddRecvStream() {
4182 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++));
4183 }
4184
4185 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
4186 size_t num_streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02004187 fake_call_.GetVideoReceiveStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004188 EXPECT_TRUE(channel_->AddRecvStream(sp));
4189 std::vector<FakeVideoReceiveStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02004190 fake_call_.GetVideoReceiveStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004191 EXPECT_EQ(num_streams + 1, streams.size());
4192 return streams[streams.size() - 1];
4193 }
4194
skvlad11a9cbf2016-10-07 11:53:05 -07004195 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +02004196 FakeCall fake_call_;
4197 WebRtcVideoEngine2 engine_;
kwiberg686a8ef2016-02-26 03:00:35 -08004198 std::unique_ptr<VideoMediaChannel> channel_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02004199 uint32_t last_ssrc_;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004200};
4201
4202TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith2SimulcastStreams) {
sprang429600d2017-01-26 06:12:26 -08004203 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 640, 360, 2, 2, false,
4204 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004205}
4206
4207TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith3SimulcastStreams) {
sprang429600d2017-01-26 06:12:26 -08004208 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, false,
4209 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004210}
4211
4212// Test that we normalize send codec format size in simulcast.
4213TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
sprang429600d2017-01-26 06:12:26 -08004214 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 541, 271, 2, 2, false,
4215 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004216}
sprang429600d2017-01-26 06:12:26 -08004217
4218TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsForScreenshare) {
4219 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
4220 false);
4221}
4222
4223TEST_F(WebRtcVideoChannel2SimulcastTest,
4224 SetSendCodecsForConferenceModeScreenshare) {
4225 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
4226 true);
4227}
4228
4229TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsForSimulcastScreenshare) {
4230 webrtc::test::ScopedFieldTrials override_field_trials_(
4231 "WebRTC-SimulcastScreenshare/Enabled/");
4232 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 2, true,
4233 true);
4234}
4235
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004236} // namespace cricket