blob: ea384e02224a297fa7bfd42ba294d548669f7800 [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>
brandtr468da7c2016-11-22 02:16:47 -080012#include <list>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000013#include <map>
kwiberg686a8ef2016-02-26 03:00:35 -080014#include <memory>
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000015#include <vector>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000016
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +000017#include "webrtc/base/arraysize.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000018#include "webrtc/base/gunit.h"
19#include "webrtc/base/stringutils.h"
magjed725e4842016-11-16 00:48:13 -080020#include "webrtc/common_video/h264/profile_level_id.h"
skvlad11a9cbf2016-10-07 11:53:05 -070021#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
kjellandera96e2d72016-02-04 23:52:28 -080022#include "webrtc/media/base/testutils.h"
23#include "webrtc/media/base/videoengine_unittest.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010024#include "webrtc/media/engine/fakewebrtccall.h"
25#include "webrtc/media/engine/fakewebrtcvideoengine.h"
26#include "webrtc/media/engine/simulcast.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010027#include "webrtc/media/engine/webrtcvideoengine2.h"
28#include "webrtc/media/engine/webrtcvoiceengine.h"
stefanc1aeaf02015-10-15 07:26:07 -070029#include "webrtc/test/field_trial.h"
pbos@webrtc.org42684be2014-10-03 11:25:45 +000030#include "webrtc/video_encoder.h"
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000031
isheriff6f8d6862016-05-26 11:24:55 -070032using webrtc::RtpExtension;
33
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000034namespace {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000035static const int kDefaultQpMax = 56;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000036
noahricd10a68e2015-07-10 11:27:55 -070037static const uint8_t kRedRtxPayloadType = 125;
38
Peter Boström0c4e06b2015-10-07 12:23:21 +020039static const uint32_t kSsrcs1[] = {1};
40static const uint32_t kSsrcs3[] = {1, 2, 3};
41static const uint32_t kRtxSsrcs1[] = {4};
brandtr468da7c2016-11-22 02:16:47 -080042static const uint32_t kFlexfecSsrc = 5;
Peter Boström0c4e06b2015-10-07 12:23:21 +020043static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE;
pbos@webrtc.org3c107582014-07-20 15:27:35 +000044static const char kUnsupportedExtensionName[] =
45 "urn:ietf:params:rtp-hdrext:unsupported";
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000046
magjed509e4fe2016-11-18 01:34:11 -080047cricket::VideoCodec RemoveFeedbackParams(cricket::VideoCodec&& codec) {
48 codec.feedback_params = cricket::FeedbackParams();
49 return codec;
50}
51
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000052void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) {
53 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
54 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
55 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
56 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
57 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
58 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
59 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
stefan43edf0f2015-11-20 18:05:48 -080060 cricket::kRtcpFbParamTransportCc, cricket::kParamValueEmpty)));
61 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000062 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
63}
64
magjed725e4842016-11-16 00:48:13 -080065// Return true if any codec in |codecs| is an RTX codec with associated payload
66// type |payload_type|.
67bool HasRtxCodec(const std::vector<cricket::VideoCodec>& codecs,
68 int payload_type) {
69 for (const cricket::VideoCodec& codec : codecs) {
70 int associated_payload_type;
71 if (cricket::CodecNamesEq(codec.name.c_str(), "rtx") &&
72 codec.GetParam(cricket::kCodecParamAssociatedPayloadType,
73 &associated_payload_type) &&
74 associated_payload_type == payload_type) {
75 return true;
76 }
77 }
78 return false;
79}
80
nisse64ec8f82016-09-27 00:17:25 -070081static rtc::scoped_refptr<webrtc::VideoFrameBuffer> CreateBlackFrameBuffer(
82 int width,
83 int height) {
84 rtc::scoped_refptr<webrtc::I420Buffer> buffer =
85 webrtc::I420Buffer::Create(width, height);
86 buffer->SetToBlack();
87 return buffer;
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +000088}
89
Shao Changbine62202f2015-04-21 20:24:50 +080090void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config,
91 const std::map<int, int>& rtx_types) {
92 std::map<int, int>::const_iterator it;
93 it = rtx_types.find(config.encoder_settings.payload_type);
94 EXPECT_TRUE(it != rtx_types.end() &&
95 it->second == config.rtp.rtx.payload_type);
96
brandtrb5f2c3f2016-10-04 23:28:39 -070097 if (config.rtp.ulpfec.red_rtx_payload_type != -1) {
98 it = rtx_types.find(config.rtp.ulpfec.red_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +080099 EXPECT_TRUE(it != rtx_types.end() &&
brandtrb5f2c3f2016-10-04 23:28:39 -0700100 it->second == config.rtp.ulpfec.red_rtx_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800101 }
102}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000103} // namespace
104
105namespace cricket {
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000106class WebRtcVideoEngine2Test : public ::testing::Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000107 public:
stefanc1aeaf02015-10-15 07:26:07 -0700108 WebRtcVideoEngine2Test() : WebRtcVideoEngine2Test("") {}
109 explicit WebRtcVideoEngine2Test(const char* field_trials)
stefanc1aeaf02015-10-15 07:26:07 -0700110 : override_field_trials_(field_trials),
skvlad11a9cbf2016-10-07 11:53:05 -0700111 call_(webrtc::Call::Create(webrtc::Call::Config(&event_log_))),
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200112 engine_() {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000113 std::vector<VideoCodec> engine_codecs = engine_.codecs();
henrikg91d6ede2015-09-17 00:24:34 -0700114 RTC_DCHECK(!engine_codecs.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000115 bool codec_set = false;
magjed509e4fe2016-11-18 01:34:11 -0800116 for (const cricket::VideoCodec& codec : engine_codecs) {
117 if (codec.name == "rtx") {
Shao Changbine62202f2015-04-21 20:24:50 +0800118 int associated_payload_type;
magjed509e4fe2016-11-18 01:34:11 -0800119 if (codec.GetParam(kCodecParamAssociatedPayloadType,
120 &associated_payload_type)) {
121 default_apt_rtx_types_[associated_payload_type] = codec.id;
Shao Changbine62202f2015-04-21 20:24:50 +0800122 }
magjed509e4fe2016-11-18 01:34:11 -0800123 } else if (!codec_set && codec.name != "red" && codec.name != "ulpfec") {
124 default_codec_ = codec;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000125 codec_set = true;
126 }
127 }
128
henrikg91d6ede2015-09-17 00:24:34 -0700129 RTC_DCHECK(codec_set);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000130 }
131
132 protected:
magjed509e4fe2016-11-18 01:34:11 -0800133 // Find the codec in the engine with the given name. The codec must be
134 // present.
135 cricket::VideoCodec GetEngineCodec(const std::string& name);
136
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000137 VideoMediaChannel* SetUpForExternalEncoderFactory(
magjed509e4fe2016-11-18 01:34:11 -0800138 cricket::WebRtcVideoEncoderFactory* encoder_factory);
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000139
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000140 VideoMediaChannel* SetUpForExternalDecoderFactory(
141 cricket::WebRtcVideoDecoderFactory* decoder_factory,
142 const std::vector<VideoCodec>& codecs);
143
Peter Boströme4499152016-02-05 11:13:28 +0100144 void TestExtendedEncoderOveruse(bool use_external_encoder);
145
stefanc1aeaf02015-10-15 07:26:07 -0700146 webrtc::test::ScopedFieldTrials override_field_trials_;
skvlad11a9cbf2016-10-07 11:53:05 -0700147 webrtc::RtcEventLogNullImpl event_log_;
pbos@webrtc.orgf1f0d9a2015-03-02 13:30:15 +0000148 // Used in WebRtcVideoEngine2VoiceTest, but defined here so it's properly
149 // initialized when the constructor is called.
kwiberg686a8ef2016-02-26 03:00:35 -0800150 std::unique_ptr<webrtc::Call> call_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000151 WebRtcVideoEngine2 engine_;
152 VideoCodec default_codec_;
Shao Changbine62202f2015-04-21 20:24:50 +0800153 std::map<int, int> default_apt_rtx_types_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000154};
155
Peter Boström12996152016-05-14 02:03:18 +0200156TEST_F(WebRtcVideoEngine2Test, AnnouncesVp9AccordingToBuildFlags) {
157 bool claims_vp9_support = false;
158 for (const cricket::VideoCodec& codec : engine_.codecs()) {
159 if (codec.name == "VP9") {
160 claims_vp9_support = true;
161 break;
162 }
163 }
164#if defined(RTC_DISABLE_VP9)
165 EXPECT_FALSE(claims_vp9_support);
166#else
167 EXPECT_TRUE(claims_vp9_support);
168#endif // defined(RTC_DISABLE_VP9)
169}
170
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000171TEST_F(WebRtcVideoEngine2Test, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
172 std::vector<VideoCodec> engine_codecs = engine_.codecs();
173 for (size_t i = 0; i < engine_codecs.size(); ++i) {
174 if (engine_codecs[i].name != kRtxCodecName)
175 continue;
176 int associated_payload_type;
177 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000178 &associated_payload_type));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000179 EXPECT_EQ(default_codec_.id, associated_payload_type);
180 return;
181 }
182 FAIL() << "No RTX codec found among default codecs.";
183}
184
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000185TEST_F(WebRtcVideoEngine2Test, SupportsTimestampOffsetHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100186 RtpCapabilities capabilities = engine_.GetCapabilities();
187 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700188 for (const RtpExtension& extension : capabilities.header_extensions) {
189 if (extension.uri == RtpExtension::kTimestampOffsetUri) {
190 EXPECT_EQ(RtpExtension::kTimestampOffsetDefaultId, extension.id);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000191 return;
192 }
193 }
194 FAIL() << "Timestamp offset extension not in header-extension list.";
195}
196
197TEST_F(WebRtcVideoEngine2Test, SupportsAbsoluteSenderTimeHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100198 RtpCapabilities capabilities = engine_.GetCapabilities();
199 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700200 for (const RtpExtension& extension : capabilities.header_extensions) {
201 if (extension.uri == RtpExtension::kAbsSendTimeUri) {
202 EXPECT_EQ(RtpExtension::kAbsSendTimeDefaultId, extension.id);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000203 return;
204 }
205 }
206 FAIL() << "Absolute Sender Time extension not in header-extension list.";
207}
208
Stefan Holmer06a5e1a2016-09-02 12:36:49 +0200209TEST_F(WebRtcVideoEngine2Test, SupportsTransportSequenceNumberHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100210 RtpCapabilities capabilities = engine_.GetCapabilities();
211 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700212 for (const RtpExtension& extension : capabilities.header_extensions) {
213 if (extension.uri == RtpExtension::kTransportSequenceNumberUri) {
214 EXPECT_EQ(RtpExtension::kTransportSequenceNumberDefaultId, extension.id);
stefanc1aeaf02015-10-15 07:26:07 -0700215 return;
216 }
217 }
218 FAIL() << "Transport sequence number extension not in header-extension list.";
219}
220
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700221TEST_F(WebRtcVideoEngine2Test, SupportsVideoRotationHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100222 RtpCapabilities capabilities = engine_.GetCapabilities();
223 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700224 for (const RtpExtension& extension : capabilities.header_extensions) {
225 if (extension.uri == RtpExtension::kVideoRotationUri) {
226 EXPECT_EQ(RtpExtension::kVideoRotationDefaultId, extension.id);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700227 return;
228 }
229 }
230 FAIL() << "Video Rotation extension not in header-extension list.";
231}
232
233TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionBeforeCapturer) {
234 // Allocate the capturer first to prevent early destruction before channel's
235 // dtor is called.
236 cricket::FakeVideoCapturer capturer;
237
238 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700239 encoder_factory.AddSupportedVideoCodecType("VP8");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700240
kwiberg686a8ef2016-02-26 03:00:35 -0800241 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800242 SetUpForExternalEncoderFactory(&encoder_factory));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700243 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
244
245 // Add CVO extension.
246 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800247 cricket::VideoSendParameters parameters;
248 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200249 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700250 RtpExtension(RtpExtension::kVideoRotationUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200251 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700252
253 // Set capturer.
deadbeef5a4a75a2016-06-02 16:23:38 -0700254 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700255
256 // Verify capturer has turned off applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700257 EXPECT_FALSE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700258
259 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200260 parameters.extensions.clear();
261 EXPECT_TRUE(channel->SetSendParameters(parameters));
nisse47ac4622016-05-25 08:47:01 -0700262 EXPECT_TRUE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700263}
264
perkj91e1c152016-03-02 05:34:00 -0800265TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionBeforeAddSendStream) {
266 // Allocate the capturer first to prevent early destruction before channel's
267 // dtor is called.
268 cricket::FakeVideoCapturer capturer;
269
270 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700271 encoder_factory.AddSupportedVideoCodecType("VP8");
perkj91e1c152016-03-02 05:34:00 -0800272
273 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800274 SetUpForExternalEncoderFactory(&encoder_factory));
perkj91e1c152016-03-02 05:34:00 -0800275 // Add CVO extension.
276 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800277 cricket::VideoSendParameters parameters;
278 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj91e1c152016-03-02 05:34:00 -0800279 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700280 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkj91e1c152016-03-02 05:34:00 -0800281 EXPECT_TRUE(channel->SetSendParameters(parameters));
282 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
283
284 // Set capturer.
deadbeef5a4a75a2016-06-02 16:23:38 -0700285 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
perkj91e1c152016-03-02 05:34:00 -0800286
287 // Verify capturer has turned off applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700288 EXPECT_FALSE(capturer.apply_rotation());
perkj91e1c152016-03-02 05:34:00 -0800289}
290
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700291TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionAfterCapturer) {
292 cricket::FakeVideoCapturer capturer;
293
294 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700295 encoder_factory.AddSupportedVideoCodecType("VP8");
296 encoder_factory.AddSupportedVideoCodecType("VP9");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700297
kwiberg686a8ef2016-02-26 03:00:35 -0800298 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800299 SetUpForExternalEncoderFactory(&encoder_factory));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700300 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
301
302 // Set capturer.
deadbeef5a4a75a2016-06-02 16:23:38 -0700303 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700304
perkjcaafdba2016-03-20 07:34:29 -0700305 // Verify capturer has turned on applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700306 EXPECT_TRUE(capturer.apply_rotation());
perkjcaafdba2016-03-20 07:34:29 -0700307
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700308 // Add CVO extension.
309 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800310 cricket::VideoSendParameters parameters;
311 parameters.codecs.push_back(GetEngineCodec("VP8"));
312 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200313 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700314 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkjcaafdba2016-03-20 07:34:29 -0700315 // Also remove the first codec to trigger a codec change as well.
316 parameters.codecs.erase(parameters.codecs.begin());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200317 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700318
319 // Verify capturer has turned off applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700320 EXPECT_FALSE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700321
322 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200323 parameters.extensions.clear();
324 EXPECT_TRUE(channel->SetSendParameters(parameters));
nisse47ac4622016-05-25 08:47:01 -0700325 EXPECT_TRUE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700326}
327
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000328TEST_F(WebRtcVideoEngine2Test, SetSendFailsBeforeSettingCodecs) {
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200329 engine_.Init();
kwiberg686a8ef2016-02-26 03:00:35 -0800330 std::unique_ptr<VideoMediaChannel> channel(
nisse51542be2016-02-12 02:27:06 -0800331 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions()));
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000332
333 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
334
335 EXPECT_FALSE(channel->SetSend(true))
336 << "Channel should not start without codecs.";
337 EXPECT_TRUE(channel->SetSend(false))
338 << "Channel should be stoppable even without set codecs.";
339}
340
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000341TEST_F(WebRtcVideoEngine2Test, GetStatsWithoutSendCodecsSetDoesNotCrash) {
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200342 engine_.Init();
kwiberg686a8ef2016-02-26 03:00:35 -0800343 std::unique_ptr<VideoMediaChannel> channel(
nisse51542be2016-02-12 02:27:06 -0800344 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions()));
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000345 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
346 VideoMediaInfo info;
347 channel->GetStats(&info);
348}
349
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000350TEST_F(WebRtcVideoEngine2Test, UseExternalFactoryForVp8WhenSupported) {
351 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700352 encoder_factory.AddSupportedVideoCodecType("VP8");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000353
kwiberg686a8ef2016-02-26 03:00:35 -0800354 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800355 SetUpForExternalEncoderFactory(&encoder_factory));
Sergey Ulanove2b15012016-11-22 16:08:30 -0800356 channel->OnReadyToSend(true);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000357
358 EXPECT_TRUE(
359 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Per21d45d22016-10-30 21:37:57 +0100360 EXPECT_EQ(0, encoder_factory.GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000361 EXPECT_TRUE(channel->SetSend(true));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000362 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700363 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000364 EXPECT_EQ(cricket::CS_RUNNING,
365 capturer.Start(capturer.GetSupportedFormats()->front()));
366 EXPECT_TRUE(capturer.CaptureFrame());
Per21d45d22016-10-30 21:37:57 +0100367 // Sending one frame will have allocate the encoder.
368 ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(1));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000369 EXPECT_TRUE_WAIT(encoder_factory.encoders()[0]->GetNumEncodedFrames() > 0,
370 kTimeout);
371
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000372 int num_created_encoders = encoder_factory.GetNumCreatedEncoders();
Per21d45d22016-10-30 21:37:57 +0100373 EXPECT_EQ(num_created_encoders, 1);
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000374
375 // Setting codecs of the same type should not reallocate any encoders
376 // (expecting a no-op).
magjed509e4fe2016-11-18 01:34:11 -0800377 cricket::VideoSendParameters parameters;
378 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200379 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000380 EXPECT_EQ(num_created_encoders, encoder_factory.GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000381
382 // Remove stream previously added to free the external encoder instance.
383 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
384 EXPECT_EQ(0u, encoder_factory.encoders().size());
385}
386
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700387// Test that when an external encoder factory supports a codec we don't
388// internally support, we still add an RTX codec for it.
389// TODO(deadbeef): Currently this test is only effective if WebRTC is
390// built with no internal H264 support. This test should be updated
391// if/when we start adding RTX codecs for unrecognized codec names.
392TEST_F(WebRtcVideoEngine2Test, RtxCodecAddedForExternalCodec) {
magjed725e4842016-11-16 00:48:13 -0800393 using webrtc::H264::ProfileLevelIdToString;
394 using webrtc::H264::ProfileLevelId;
395 using webrtc::H264::kLevel1;
396 cricket::VideoCodec h264_constrained_baseline("H264");
397 h264_constrained_baseline.params[kH264FmtpProfileLevelId] =
398 *ProfileLevelIdToString(
399 ProfileLevelId(webrtc::H264::kProfileConstrainedBaseline, kLevel1));
400 cricket::VideoCodec h264_constrained_high("H264");
401 h264_constrained_high.params[kH264FmtpProfileLevelId] =
402 *ProfileLevelIdToString(
403 ProfileLevelId(webrtc::H264::kProfileConstrainedHigh, kLevel1));
404 cricket::VideoCodec h264_high("H264");
405 h264_high.params[kH264FmtpProfileLevelId] = *ProfileLevelIdToString(
406 ProfileLevelId(webrtc::H264::kProfileHigh, kLevel1));
407
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700408 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed725e4842016-11-16 00:48:13 -0800409 encoder_factory.AddSupportedVideoCodec(h264_constrained_baseline);
410 encoder_factory.AddSupportedVideoCodec(h264_constrained_high);
411 encoder_factory.AddSupportedVideoCodec(h264_high);
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700412 engine_.SetExternalEncoderFactory(&encoder_factory);
413 engine_.Init();
414
magjed725e4842016-11-16 00:48:13 -0800415 // First figure out what payload types the test codecs got assigned.
416 const std::vector<cricket::VideoCodec> codecs = engine_.codecs();
magjed509e4fe2016-11-18 01:34:11 -0800417 // Now search for RTX codecs for them. Expect that they all have associated
418 // RTX codecs.
magjed725e4842016-11-16 00:48:13 -0800419 EXPECT_TRUE(HasRtxCodec(
420 codecs, FindMatchingCodec(codecs, h264_constrained_baseline)->id));
421 EXPECT_TRUE(HasRtxCodec(
422 codecs, FindMatchingCodec(codecs, h264_constrained_high)->id));
magjed509e4fe2016-11-18 01:34:11 -0800423 EXPECT_TRUE(HasRtxCodec(
magjed725e4842016-11-16 00:48:13 -0800424 codecs, FindMatchingCodec(codecs, h264_high)->id));
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700425}
426
Peter Boströme4499152016-02-05 11:13:28 +0100427void WebRtcVideoEngine2Test::TestExtendedEncoderOveruse(
428 bool use_external_encoder) {
429 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700430 encoder_factory.AddSupportedVideoCodecType("VP8");
kwiberg686a8ef2016-02-26 03:00:35 -0800431 std::unique_ptr<VideoMediaChannel> channel;
skvlad11a9cbf2016-10-07 11:53:05 -0700432 FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_));
Peter Boströme4499152016-02-05 11:13:28 +0100433 call_.reset(fake_call);
434 if (use_external_encoder) {
magjed509e4fe2016-11-18 01:34:11 -0800435 channel.reset(SetUpForExternalEncoderFactory(&encoder_factory));
Peter Boströme4499152016-02-05 11:13:28 +0100436 } else {
437 engine_.Init();
nisse51542be2016-02-12 02:27:06 -0800438 channel.reset(
439 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions()));
Peter Boströme4499152016-02-05 11:13:28 +0100440 }
441 ASSERT_TRUE(
442 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
magjed509e4fe2016-11-18 01:34:11 -0800443 cricket::VideoSendParameters parameters;
444 parameters.codecs.push_back(GetEngineCodec("VP8"));
Peter Boströme4499152016-02-05 11:13:28 +0100445 EXPECT_TRUE(channel->SetSendParameters(parameters));
446 EXPECT_TRUE(channel->SetSend(true));
447 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
448
449 EXPECT_EQ(use_external_encoder,
450 stream->GetConfig().encoder_settings.full_overuse_time);
451 // Remove stream previously added to free the external encoder instance.
452 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
453}
454
455TEST_F(WebRtcVideoEngine2Test, EnablesFullEncoderTimeForExternalEncoders) {
456 TestExtendedEncoderOveruse(true);
457}
458
459TEST_F(WebRtcVideoEngine2Test, DisablesFullEncoderTimeForNonExternalEncoders) {
460 TestExtendedEncoderOveruse(false);
461}
462
Peter Boström12996152016-05-14 02:03:18 +0200463#if !defined(RTC_DISABLE_VP9)
Peter Boström53eda3d2015-03-27 15:53:18 +0100464TEST_F(WebRtcVideoEngine2Test, CanConstructDecoderForVp9EncoderFactory) {
465 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700466 encoder_factory.AddSupportedVideoCodecType("VP9");
Peter Boström53eda3d2015-03-27 15:53:18 +0100467
kwiberg686a8ef2016-02-26 03:00:35 -0800468 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800469 SetUpForExternalEncoderFactory(&encoder_factory));
Peter Boström53eda3d2015-03-27 15:53:18 +0100470
471 EXPECT_TRUE(
472 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
473}
Peter Boström12996152016-05-14 02:03:18 +0200474#endif // !defined(RTC_DISABLE_VP9)
Peter Boström53eda3d2015-03-27 15:53:18 +0100475
qiangchenc27d89f2015-07-16 10:27:16 -0700476TEST_F(WebRtcVideoEngine2Test, PropagatesInputFrameTimestamp) {
477 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700478 encoder_factory.AddSupportedVideoCodecType("VP8");
skvlad11a9cbf2016-10-07 11:53:05 -0700479 FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200480 call_.reset(fake_call);
kwiberg686a8ef2016-02-26 03:00:35 -0800481 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800482 SetUpForExternalEncoderFactory(&encoder_factory));
qiangchenc27d89f2015-07-16 10:27:16 -0700483
484 EXPECT_TRUE(
485 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
486
487 FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700488 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
qiangchenc27d89f2015-07-16 10:27:16 -0700489 capturer.Start(cricket::VideoFormat(1280, 720,
490 cricket::VideoFormat::FpsToInterval(60),
491 cricket::FOURCC_I420));
492 channel->SetSend(true);
493
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200494 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
qiangchenc27d89f2015-07-16 10:27:16 -0700495
496 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700497 int64_t last_timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700498 for (int i = 0; i < 10; i++) {
499 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700500 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700501 int64_t interval = timestamp - last_timestamp;
502
503 // Precision changes from nanosecond to millisecond.
504 // Allow error to be no more than 1.
505 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1);
506
507 last_timestamp = timestamp;
508 }
509
510 capturer.Start(cricket::VideoFormat(1280, 720,
511 cricket::VideoFormat::FpsToInterval(30),
512 cricket::FOURCC_I420));
513
514 EXPECT_TRUE(capturer.CaptureFrame());
515 last_timestamp = stream->GetLastTimestamp();
516 for (int i = 0; i < 10; i++) {
517 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700518 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700519 int64_t interval = timestamp - last_timestamp;
520
521 // Precision changes from nanosecond to millisecond.
522 // Allow error to be no more than 1.
523 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1);
524
525 last_timestamp = timestamp;
526 }
527
528 // Remove stream previously added to free the external encoder instance.
529 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
530}
531
magjed509e4fe2016-11-18 01:34:11 -0800532cricket::VideoCodec WebRtcVideoEngine2Test::GetEngineCodec(
533 const std::string& name) {
534 for (const cricket::VideoCodec& engine_codec : engine_.codecs()) {
535 if (CodecNamesEq(name, engine_codec.name))
536 return engine_codec;
537 }
538 // This point should never be reached.
539 ADD_FAILURE() << "Unrecognized codec name: " << name;
540 return cricket::VideoCodec();
541}
542
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000543VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalEncoderFactory(
magjed509e4fe2016-11-18 01:34:11 -0800544 cricket::WebRtcVideoEncoderFactory* encoder_factory) {
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000545 engine_.SetExternalEncoderFactory(encoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200546 engine_.Init();
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000547
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000548 VideoMediaChannel* channel =
nisse51542be2016-02-12 02:27:06 -0800549 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200550 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800551 // We need to look up the codec in the engine to get the correct payload type.
552 for (const VideoCodec& codec : encoder_factory->supported_codecs())
553 parameters.codecs.push_back(GetEngineCodec(codec.name));
554
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200555 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000556
557 return channel;
558}
559
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000560VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalDecoderFactory(
561 cricket::WebRtcVideoDecoderFactory* decoder_factory,
562 const std::vector<VideoCodec>& codecs) {
563 engine_.SetExternalDecoderFactory(decoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200564 engine_.Init();
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000565
566 VideoMediaChannel* channel =
nisse51542be2016-02-12 02:27:06 -0800567 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200568 cricket::VideoRecvParameters parameters;
569 parameters.codecs = codecs;
570 EXPECT_TRUE(channel->SetRecvParameters(parameters));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000571
572 return channel;
573}
574
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000575TEST_F(WebRtcVideoEngine2Test, UsesSimulcastAdapterForVp8Factories) {
576 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700577 encoder_factory.AddSupportedVideoCodecType("VP8");
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000578
kwiberg686a8ef2016-02-26 03:00:35 -0800579 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800580 SetUpForExternalEncoderFactory(&encoder_factory));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000581
Peter Boström0c4e06b2015-10-07 12:23:21 +0200582 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000583
584 EXPECT_TRUE(
585 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
586 EXPECT_TRUE(channel->SetSend(true));
587
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000588 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700589 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, &capturer));
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000590 EXPECT_EQ(cricket::CS_RUNNING,
591 capturer.Start(capturer.GetSupportedFormats()->front()));
592 EXPECT_TRUE(capturer.CaptureFrame());
593
pbos14fe7082016-04-20 06:35:56 -0700594 ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(2));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000595
596 // Verify that encoders are configured for simulcast through adapter
597 // (increasing resolution and only configured to send one stream each).
598 int prev_width = -1;
599 for (size_t i = 0; i < encoder_factory.encoders().size(); ++i) {
pbos14fe7082016-04-20 06:35:56 -0700600 ASSERT_TRUE(encoder_factory.encoders()[i]->WaitForInitEncode());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000601 webrtc::VideoCodec codec_settings =
602 encoder_factory.encoders()[i]->GetCodecSettings();
603 EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
604 EXPECT_GT(codec_settings.width, prev_width);
605 prev_width = codec_settings.width;
606 }
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000607
deadbeef5a4a75a2016-06-02 16:23:38 -0700608 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, nullptr));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000609
610 channel.reset();
611 ASSERT_EQ(0u, encoder_factory.encoders().size());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000612}
613
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000614TEST_F(WebRtcVideoEngine2Test, ChannelWithExternalH264CanChangeToInternalVp8) {
615 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700616 encoder_factory.AddSupportedVideoCodecType("H264");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000617
kwiberg686a8ef2016-02-26 03:00:35 -0800618 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800619 SetUpForExternalEncoderFactory(&encoder_factory));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000620
621 EXPECT_TRUE(
622 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
623 ASSERT_EQ(1u, encoder_factory.encoders().size());
624
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200625 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800626 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200627 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000628 ASSERT_EQ(0u, encoder_factory.encoders().size());
629}
630
631TEST_F(WebRtcVideoEngine2Test,
632 DontUseExternalEncoderFactoryForUnsupportedCodecs) {
633 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700634 encoder_factory.AddSupportedVideoCodecType("H264");
magjed509e4fe2016-11-18 01:34:11 -0800635
636 engine_.SetExternalEncoderFactory(&encoder_factory);
637 engine_.Init();
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000638
kwiberg686a8ef2016-02-26 03:00:35 -0800639 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800640 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions()));
641 cricket::VideoSendParameters parameters;
642 parameters.codecs.push_back(GetEngineCodec("VP8"));
643 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000644
645 EXPECT_TRUE(
646 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000647 // Make sure DestroyVideoEncoder was called on the factory.
648 ASSERT_EQ(0u, encoder_factory.encoders().size());
649}
650
651TEST_F(WebRtcVideoEngine2Test,
652 UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
653 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700654 encoder_factory.AddSupportedVideoCodecType("VP8");
655 encoder_factory.AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000656
magjed509e4fe2016-11-18 01:34:11 -0800657 engine_.SetExternalEncoderFactory(&encoder_factory);
658 engine_.Init();
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000659
kwiberg686a8ef2016-02-26 03:00:35 -0800660 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800661 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions()));
662 cricket::VideoSendParameters parameters;
663 parameters.codecs.push_back(GetEngineCodec("VP8"));
664 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000665
Peter Boström0c4e06b2015-10-07 12:23:21 +0200666 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000667
668 EXPECT_TRUE(
669 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
670 EXPECT_TRUE(channel->SetSend(true));
671
672 // Send a fake frame, or else the media engine will configure the simulcast
673 // encoder adapter at a low-enough size that it'll only create a single
674 // encoder layer.
675 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700676 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, &capturer));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000677 EXPECT_EQ(cricket::CS_RUNNING,
678 capturer.Start(capturer.GetSupportedFormats()->front()));
679 EXPECT_TRUE(capturer.CaptureFrame());
680
pbos14fe7082016-04-20 06:35:56 -0700681 ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(2));
682 ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000683 EXPECT_EQ(webrtc::kVideoCodecVP8,
684 encoder_factory.encoders()[0]->GetCodecSettings().codecType);
685
686 channel.reset();
687 // Make sure DestroyVideoEncoder was called on the factory.
688 EXPECT_EQ(0u, encoder_factory.encoders().size());
689}
690
691TEST_F(WebRtcVideoEngine2Test,
692 DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
693 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700694 encoder_factory.AddSupportedVideoCodecType("VP8");
695 encoder_factory.AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000696
magjed509e4fe2016-11-18 01:34:11 -0800697 engine_.SetExternalEncoderFactory(&encoder_factory);
698 engine_.Init();
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000699
kwiberg686a8ef2016-02-26 03:00:35 -0800700 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800701 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions()));
702 cricket::VideoSendParameters parameters;
703 parameters.codecs.push_back(GetEngineCodec("H264"));
704 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000705
706 EXPECT_TRUE(
707 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
708 ASSERT_EQ(1u, encoder_factory.encoders().size());
Per21d45d22016-10-30 21:37:57 +0100709
710 // Send a frame of 720p. This should trigger a "real" encoder initialization.
711 cricket::VideoFormat format(
712 1280, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
713 cricket::FakeVideoCapturer capturer;
714 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
715 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format));
716 EXPECT_TRUE(capturer.CaptureFrame());
pbos14fe7082016-04-20 06:35:56 -0700717 ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000718 EXPECT_EQ(webrtc::kVideoCodecH264,
719 encoder_factory.encoders()[0]->GetCodecSettings().codecType);
720
721 channel.reset();
722 // Make sure DestroyVideoEncoder was called on the factory.
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000723 ASSERT_EQ(0u, encoder_factory.encoders().size());
724}
725
noahricfdac5162015-08-27 01:59:29 -0700726TEST_F(WebRtcVideoEngine2Test, SimulcastDisabledForH264) {
727 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700728 encoder_factory.AddSupportedVideoCodecType("H264");
noahricfdac5162015-08-27 01:59:29 -0700729
kwiberg686a8ef2016-02-26 03:00:35 -0800730 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800731 SetUpForExternalEncoderFactory(&encoder_factory));
noahricfdac5162015-08-27 01:59:29 -0700732
Peter Boström0c4e06b2015-10-07 12:23:21 +0200733 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
noahricfdac5162015-08-27 01:59:29 -0700734 EXPECT_TRUE(
735 channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs)));
Peter Boströmce23bee2016-02-02 14:14:30 +0100736
737 // Send a frame of 720p. This should trigger a "real" encoder initialization.
noahricfdac5162015-08-27 01:59:29 -0700738 cricket::VideoFormat format(
739 1280, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
Peter Boströmce23bee2016-02-02 14:14:30 +0100740 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700741 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], true, nullptr, &capturer));
Peter Boströmce23bee2016-02-02 14:14:30 +0100742 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format));
743 EXPECT_TRUE(capturer.CaptureFrame());
744
noahricfdac5162015-08-27 01:59:29 -0700745 ASSERT_EQ(1u, encoder_factory.encoders().size());
746 FakeWebRtcVideoEncoder* encoder = encoder_factory.encoders()[0];
pbos14fe7082016-04-20 06:35:56 -0700747 ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode());
noahricfdac5162015-08-27 01:59:29 -0700748 EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
749 EXPECT_EQ(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
deadbeef5a4a75a2016-06-02 16:23:38 -0700750 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], true, nullptr, nullptr));
noahricfdac5162015-08-27 01:59:29 -0700751}
752
hbosbab934b2016-01-27 01:36:03 -0800753// Test that external codecs are added to the end of the supported codec list.
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000754TEST_F(WebRtcVideoEngine2Test, ReportSupportedExternalCodecs) {
755 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700756 encoder_factory.AddSupportedVideoCodecType("FakeExternalCodec");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000757 engine_.SetExternalEncoderFactory(&encoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200758 engine_.Init();
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000759
760 std::vector<cricket::VideoCodec> codecs(engine_.codecs());
761 ASSERT_GE(codecs.size(), 2u);
762 cricket::VideoCodec internal_codec = codecs.front();
763 cricket::VideoCodec external_codec = codecs.back();
764
765 // The external codec will appear at last.
766 EXPECT_EQ("VP8", internal_codec.name);
hbosbab934b2016-01-27 01:36:03 -0800767 EXPECT_EQ("FakeExternalCodec", external_codec.name);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000768}
769
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000770TEST_F(WebRtcVideoEngine2Test, RegisterExternalDecodersIfSupported) {
771 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
772 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200773 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800774 parameters.codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000775
kwiberg686a8ef2016-02-26 03:00:35 -0800776 std::unique_ptr<VideoMediaChannel> channel(
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200777 SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000778
779 EXPECT_TRUE(
780 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
781 ASSERT_EQ(1u, decoder_factory.decoders().size());
782
783 // Setting codecs of the same type should not reallocate the decoder.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200784 EXPECT_TRUE(channel->SetRecvParameters(parameters));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000785 EXPECT_EQ(1, decoder_factory.GetNumCreatedDecoders());
786
787 // Remove stream previously added to free the external decoder instance.
788 EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
789 EXPECT_EQ(0u, decoder_factory.decoders().size());
790}
791
792// Verifies that we can set up decoders that are not internally supported.
793TEST_F(WebRtcVideoEngine2Test, RegisterExternalH264DecoderIfSupported) {
794 // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We
795 // can't even query the WebRtcVideoDecoderFactory for supported codecs.
796 // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
797 // codecs.
798 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700799 encoder_factory.AddSupportedVideoCodecType("H264");
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000800 engine_.SetExternalEncoderFactory(&encoder_factory);
801 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
802 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264);
803 std::vector<cricket::VideoCodec> codecs;
magjed509e4fe2016-11-18 01:34:11 -0800804 codecs.push_back(GetEngineCodec("H264"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000805
kwiberg686a8ef2016-02-26 03:00:35 -0800806 std::unique_ptr<VideoMediaChannel> channel(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000807 SetUpForExternalDecoderFactory(&decoder_factory, codecs));
808
809 EXPECT_TRUE(
810 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
811 ASSERT_EQ(1u, decoder_factory.decoders().size());
812}
813
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000814class WebRtcVideoChannel2BaseTest
815 : public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> {
816 protected:
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000817 typedef VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> Base;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000818
magjed509e4fe2016-11-18 01:34:11 -0800819 cricket::VideoCodec GetEngineCodec(const std::string& name) {
820 for (const cricket::VideoCodec& engine_codec : engine_.codecs()) {
821 if (CodecNamesEq(name, engine_codec.name))
822 return engine_codec;
823 }
824 // This point should never be reached.
825 ADD_FAILURE() << "Unrecognized codec name: " << name;
826 return cricket::VideoCodec();
827 }
828
829 cricket::VideoCodec DefaultCodec() override { return GetEngineCodec("VP8"); }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000830};
831
sakal1fd95952016-06-22 00:46:15 -0700832// Verifies that id given in stream params is passed to the decoder factory.
833TEST_F(WebRtcVideoEngine2Test, StreamParamsIdPassedToDecoderFactory) {
834 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
835 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
836 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800837 parameters.codecs.push_back(GetEngineCodec("VP8"));
sakal1fd95952016-06-22 00:46:15 -0700838
839 std::unique_ptr<VideoMediaChannel> channel(
840 SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs));
841
842 StreamParams sp = cricket::StreamParams::CreateLegacy(kSsrc);
843 sp.id = "FakeStreamParamsId";
844 EXPECT_TRUE(channel->AddRecvStream(sp));
845 EXPECT_EQ(1u, decoder_factory.decoders().size());
846
847 std::vector<cricket::VideoDecoderParams> params = decoder_factory.params();
848 ASSERT_EQ(1u, params.size());
849 EXPECT_EQ(sp.id, params[0].receive_stream_id);
850}
851
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000852#define WEBRTC_BASE_TEST(test) \
853 TEST_F(WebRtcVideoChannel2BaseTest, test) { Base::test(); }
854
855#define WEBRTC_DISABLED_BASE_TEST(test) \
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000856 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_##test) { Base::test(); }
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000857
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000858WEBRTC_BASE_TEST(SetSend);
859WEBRTC_BASE_TEST(SetSendWithoutCodecs);
860WEBRTC_BASE_TEST(SetSendSetsTransportBufferSizes);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000861
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000862WEBRTC_BASE_TEST(GetStats);
863WEBRTC_BASE_TEST(GetStatsMultipleRecvStreams);
864WEBRTC_BASE_TEST(GetStatsMultipleSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000865
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000866WEBRTC_BASE_TEST(SetSendBandwidth);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000867
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000868WEBRTC_BASE_TEST(SetSendSsrc);
869WEBRTC_BASE_TEST(SetSendSsrcAfterSetCodecs);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000870
nisse08582ff2016-02-04 01:24:52 -0800871WEBRTC_BASE_TEST(SetSink);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000872
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000873WEBRTC_BASE_TEST(AddRemoveSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000874
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000875WEBRTC_BASE_TEST(SimulateConference);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000876
Alejandro Luebs947c02d2016-06-15 15:39:46 -0700877WEBRTC_DISABLED_BASE_TEST(AddRemoveCapturer);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000878
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000879WEBRTC_BASE_TEST(RemoveCapturerWithoutAdd);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000880
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000881WEBRTC_BASE_TEST(AddRemoveCapturerMultipleSources);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000882
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000883WEBRTC_BASE_TEST(RejectEmptyStreamParams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000884
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +0000885WEBRTC_BASE_TEST(MultipleSendStreams);
886
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000887TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Vga) {
magjed509e4fe2016-11-18 01:34:11 -0800888 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000889}
890
891TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Qvga) {
magjed509e4fe2016-11-18 01:34:11 -0800892 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000893}
894
895TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8SvcQqvga) {
magjed509e4fe2016-11-18 01:34:11 -0800896 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000897}
898
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000899TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) {
Peter Boströmd1f584b2016-04-20 16:31:53 +0200900 // Set a high bitrate to not be downscaled by VP8 due to low initial start
901 // bitrates. This currently happens at <250k, and two streams sharing 300k
902 // initially will use QVGA instead of VGA.
903 // TODO(pbos): Set up the quality scaler so that both senders reliably start
904 // at QVGA, then verify that instead.
magjed509e4fe2016-11-18 01:34:11 -0800905 cricket::VideoCodec codec = GetEngineCodec("VP8");
Peter Boströmd1f584b2016-04-20 16:31:53 +0200906 codec.params[kCodecParamStartBitrate] = "1000000";
907 Base::TwoStreamsSendAndReceive(codec);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000908}
909
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200910class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000911 public:
stefanc1aeaf02015-10-15 07:26:07 -0700912 WebRtcVideoChannel2Test() : WebRtcVideoChannel2Test("") {}
913 explicit WebRtcVideoChannel2Test(const char* field_trials)
914 : WebRtcVideoEngine2Test(field_trials), last_ssrc_(0) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000915 void SetUp() override {
skvlad11a9cbf2016-10-07 11:53:05 -0700916 fake_call_.reset(new FakeCall(webrtc::Call::Config(&event_log_)));
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200917 engine_.Init();
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200918 channel_.reset(
nisse51542be2016-02-12 02:27:06 -0800919 engine_.CreateChannel(fake_call_.get(), MediaConfig(), VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -0800920 channel_->OnReadyToSend(true);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000921 last_ssrc_ = 123;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200922 send_parameters_.codecs = engine_.codecs();
923 recv_parameters_.codecs = engine_.codecs();
924 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000925 }
926
927 protected:
928 FakeVideoSendStream* AddSendStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000929 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000930 }
931
932 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000933 size_t num_streams = fake_call_->GetVideoSendStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000934 EXPECT_TRUE(channel_->AddSendStream(sp));
935 std::vector<FakeVideoSendStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000936 fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000937 EXPECT_EQ(num_streams + 1, streams.size());
938 return streams[streams.size() - 1];
939 }
940
941 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000942 return fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000943 }
944
945 FakeVideoReceiveStream* AddRecvStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000946 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000947 }
948
949 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000950 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000951 EXPECT_TRUE(channel_->AddRecvStream(sp));
952 std::vector<FakeVideoReceiveStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000953 fake_call_->GetVideoReceiveStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000954 EXPECT_EQ(num_streams + 1, streams.size());
955 return streams[streams.size() - 1];
956 }
957
pbos@webrtc.org00873182014-11-25 14:03:34 +0000958 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
959 int expected_min_bitrate_bps,
960 const char* start_bitrate_kbps,
961 int expected_start_bitrate_bps,
962 const char* max_bitrate_kbps,
963 int expected_max_bitrate_bps) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200964 auto& codecs = send_parameters_.codecs;
965 codecs.clear();
magjed509e4fe2016-11-18 01:34:11 -0800966 codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org00873182014-11-25 14:03:34 +0000967 codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps;
968 codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps;
969 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200970 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000971
pbos@webrtc.org00873182014-11-25 14:03:34 +0000972 EXPECT_EQ(expected_min_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +0100973 fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +0000974 EXPECT_EQ(expected_start_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +0100975 fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +0000976 EXPECT_EQ(expected_max_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +0100977 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000978 }
979
isheriff6f8d6862016-05-26 11:24:55 -0700980 void TestSetSendRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000981 // Enable extension.
982 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200983 cricket::VideoSendParameters parameters = send_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -0700984 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200985 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000986 FakeVideoSendStream* send_stream =
987 AddSendStream(cricket::StreamParams::CreateLegacy(123));
988
989 // Verify the send extension id.
990 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
991 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -0700992 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000993 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200994 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000995 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
996 // receivers.
997 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
998 ->GetConfig()
999 .rtp.extensions.empty());
1000
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001001 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001002 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001003 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1004 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001005 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
1006
1007 // Verify that adding receive RTP header extensions adds them for existing
1008 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001009 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001010 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001011 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1012 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001013 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001014 }
1015
isheriff6f8d6862016-05-26 11:24:55 -07001016 void TestSetRecvRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001017 // Enable extension.
1018 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001019 cricket::VideoRecvParameters parameters = recv_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07001020 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001021 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001022
1023 FakeVideoReceiveStream* recv_stream =
1024 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1025
1026 // Verify the recv extension id.
1027 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1028 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001029 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001030 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001031 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001032
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001033 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
1034 // senders.
1035 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
1036 ->GetConfig()
1037 .rtp.extensions.empty());
1038
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001039 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001040 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001041 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
1042 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001043 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
1044
1045 // Verify that adding receive RTP header extensions adds them for existing
1046 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001047 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001048 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001049 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1050 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001051 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001052 }
1053
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001054 void TestExtensionFilter(const std::vector<std::string>& extensions,
1055 const std::string& expected_extension) {
1056 cricket::VideoSendParameters parameters = send_parameters_;
1057 int expected_id = -1;
1058 int id = 1;
1059 for (const std::string& extension : extensions) {
1060 if (extension == expected_extension)
1061 expected_id = id;
isheriff6f8d6862016-05-26 11:24:55 -07001062 parameters.extensions.push_back(RtpExtension(extension, id++));
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001063 }
1064 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1065 FakeVideoSendStream* send_stream =
1066 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1067
1068 // Verify that only one of them has been set, and that it is the one with
1069 // highest priority (transport sequence number).
1070 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1071 EXPECT_EQ(expected_id, send_stream->GetConfig().rtp.extensions[0].id);
1072 EXPECT_EQ(expected_extension,
isheriff6f8d6862016-05-26 11:24:55 -07001073 send_stream->GetConfig().rtp.extensions[0].uri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001074 }
1075
Erik Språngefbde372015-04-29 16:21:28 +02001076 void TestCpuAdaptation(bool enable_overuse, bool is_screenshare);
Peter Boström3548dd22015-05-22 18:48:36 +02001077 void TestReceiverLocalSsrcConfiguration(bool receiver_first);
magjed509e4fe2016-11-18 01:34:11 -08001078 void TestReceiveUnsignaledSsrcPacket(uint8_t payload_type,
1079 bool expect_created_receive_stream);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001080
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001081 FakeVideoSendStream* SetDenoisingOption(
nisse05103312016-03-16 02:22:50 -07001082 uint32_t ssrc,
nisse0db023a2016-03-01 04:29:59 -08001083 cricket::FakeVideoCapturer* capturer,
1084 bool enabled) {
nisse05103312016-03-16 02:22:50 -07001085 cricket::VideoOptions options;
1086 options.video_noise_reduction = rtc::Optional<bool>(enabled);
deadbeef5a4a75a2016-06-02 16:23:38 -07001087 EXPECT_TRUE(channel_->SetVideoSend(ssrc, true, &options, capturer));
nisse0db023a2016-03-01 04:29:59 -08001088 // Options only take effect on the next frame.
1089 EXPECT_TRUE(capturer->CaptureFrame());
1090
Erik Språng143cec12015-04-28 10:01:41 +02001091 return fake_call_->GetVideoSendStreams().back();
1092 }
1093
Peter Boström2feafdb2015-09-09 14:32:14 +02001094 FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) {
1095 const int kRtxSsrcOffset = 0xDEADBEEF;
Erik Språng143cec12015-04-28 10:01:41 +02001096 last_ssrc_ += 3;
Peter Boström2feafdb2015-09-09 14:32:14 +02001097 std::vector<uint32_t> ssrcs;
1098 std::vector<uint32_t> rtx_ssrcs;
1099 uint32_t num_streams = enabled ? 3 : 1;
1100 for (uint32_t i = 0; i < num_streams; ++i) {
1101 uint32_t ssrc = last_ssrc_ + i;
1102 ssrcs.push_back(ssrc);
1103 if (with_rtx) {
1104 rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset);
1105 }
Erik Språng143cec12015-04-28 10:01:41 +02001106 }
Peter Boström2feafdb2015-09-09 14:32:14 +02001107 if (with_rtx) {
1108 return AddSendStream(
1109 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1110 }
1111 return AddSendStream(CreateSimStreamParams("cname", ssrcs));
Erik Språng143cec12015-04-28 10:01:41 +02001112 }
1113
perkjfa10b552016-10-02 23:45:26 -07001114 int GetMaxEncoderBitrate() {
skvladdc1c62c2016-03-16 19:07:43 -07001115 std::vector<FakeVideoSendStream*> streams =
1116 fake_call_->GetVideoSendStreams();
perkjfa10b552016-10-02 23:45:26 -07001117 EXPECT_EQ(1u, streams.size());
skvladdc1c62c2016-03-16 19:07:43 -07001118 FakeVideoSendStream* stream = streams[streams.size() - 1];
perkjfa10b552016-10-02 23:45:26 -07001119 EXPECT_EQ(1, stream->GetEncoderConfig().number_of_streams);
1120 return stream->GetVideoStreams()[0].max_bitrate_bps;
skvladdc1c62c2016-03-16 19:07:43 -07001121 }
1122
perkjfa10b552016-10-02 23:45:26 -07001123 void SetAndExpectMaxBitrate(int global_max,
skvladdc1c62c2016-03-16 19:07:43 -07001124 int stream_max,
1125 int expected_encoder_bitrate) {
1126 VideoSendParameters limited_send_params = send_parameters_;
1127 limited_send_params.max_bandwidth_bps = global_max;
1128 EXPECT_TRUE(channel_->SetSendParameters(limited_send_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001129 webrtc::RtpParameters parameters =
1130 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07001131 EXPECT_EQ(1UL, parameters.encodings.size());
1132 parameters.encodings[0].max_bitrate_bps = stream_max;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001133 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07001134 // Read back the parameteres and verify they have the correct value
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001135 parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07001136 EXPECT_EQ(1UL, parameters.encodings.size());
1137 EXPECT_EQ(stream_max, parameters.encodings[0].max_bitrate_bps);
1138 // Verify that the new value propagated down to the encoder
perkjfa10b552016-10-02 23:45:26 -07001139 EXPECT_EQ(expected_encoder_bitrate, GetMaxEncoderBitrate());
skvladdc1c62c2016-03-16 19:07:43 -07001140 }
1141
kwiberg686a8ef2016-02-26 03:00:35 -08001142 std::unique_ptr<FakeCall> fake_call_;
1143 std::unique_ptr<VideoMediaChannel> channel_;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001144 cricket::VideoSendParameters send_parameters_;
1145 cricket::VideoRecvParameters recv_parameters_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001146 uint32_t last_ssrc_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001147};
1148
pbos8fc7fa72015-07-15 08:02:58 -07001149TEST_F(WebRtcVideoChannel2Test, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02001150 const uint32_t kVideoSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07001151 const std::string kSyncLabel = "AvSyncLabel";
1152
1153 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc);
1154 sp.sync_label = kSyncLabel;
1155 EXPECT_TRUE(channel_->AddRecvStream(sp));
1156
1157 EXPECT_EQ(1, fake_call_->GetVideoReceiveStreams().size());
1158 EXPECT_EQ(kSyncLabel,
1159 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group)
1160 << "SyncGroup should be set based on sync_label";
1161}
1162
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001163TEST_F(WebRtcVideoChannel2Test, RecvStreamWithSimAndRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001164 cricket::VideoSendParameters parameters;
1165 parameters.codecs = engine_.codecs();
1166 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001167 EXPECT_TRUE(channel_->SetSend(true));
nisse4b4dc862016-02-17 05:25:36 -08001168 parameters.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001169 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001170
1171 // Send side.
Peter Boström0c4e06b2015-10-07 12:23:21 +02001172 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
1173 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001174 FakeVideoSendStream* send_stream = AddSendStream(
1175 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1176
1177 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
1178 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
1179 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
1180
1181 // Receiver side.
1182 FakeVideoReceiveStream* recv_stream = AddRecvStream(
1183 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
Peter Boströmd8b01092016-05-12 16:44:36 +02001184 EXPECT_FALSE(recv_stream->GetConfig().rtp.rtx.empty());
1185 EXPECT_EQ(recv_stream->GetConfig().decoders.size(),
1186 recv_stream->GetConfig().rtp.rtx.size())
1187 << "RTX should be mapped for all decoders/payload types.";
1188 for (const auto& kv : recv_stream->GetConfig().rtp.rtx) {
1189 EXPECT_EQ(rtx_ssrcs[0], kv.second.ssrc);
1190 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001191}
1192
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001193TEST_F(WebRtcVideoChannel2Test, RecvStreamWithRtx) {
1194 // Setup one channel with an associated RTX stream.
1195 cricket::StreamParams params =
1196 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
1197 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
1198 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001199 EXPECT_EQ(kRtxSsrcs1[0],
1200 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001201}
1202
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001203TEST_F(WebRtcVideoChannel2Test, RecvStreamNoRtx) {
1204 // Setup one channel without an associated RTX stream.
1205 cricket::StreamParams params =
1206 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
1207 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
1208 ASSERT_TRUE(recv_stream->GetConfig().rtp.rtx.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001209}
1210
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001211TEST_F(WebRtcVideoChannel2Test, NoHeaderExtesionsByDefault) {
1212 FakeVideoSendStream* send_stream =
1213 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
1214 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
1215
1216 FakeVideoReceiveStream* recv_stream =
1217 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
1218 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001219}
1220
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001221// Test support for RTP timestamp offset header extension.
1222TEST_F(WebRtcVideoChannel2Test, SendRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001223 TestSetSendRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001224}
isheriff6f8d6862016-05-26 11:24:55 -07001225
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001226TEST_F(WebRtcVideoChannel2Test, RecvRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001227 TestSetRecvRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001228}
1229
1230// Test support for absolute send time header extension.
1231TEST_F(WebRtcVideoChannel2Test, SendAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001232 TestSetSendRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001233}
isheriff6f8d6862016-05-26 11:24:55 -07001234
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001235TEST_F(WebRtcVideoChannel2Test, RecvAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001236 TestSetRecvRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001237}
1238
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001239TEST_F(WebRtcVideoChannel2Test, FiltersExtensionsPicksTransportSeqNum) {
1240 // Enable three redundant extensions.
1241 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07001242 extensions.push_back(RtpExtension::kAbsSendTimeUri);
1243 extensions.push_back(RtpExtension::kTimestampOffsetUri);
1244 extensions.push_back(RtpExtension::kTransportSequenceNumberUri);
1245 TestExtensionFilter(extensions, RtpExtension::kTransportSequenceNumberUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001246}
1247
1248TEST_F(WebRtcVideoChannel2Test, FiltersExtensionsPicksAbsSendTime) {
1249 // Enable two redundant extensions.
1250 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07001251 extensions.push_back(RtpExtension::kAbsSendTimeUri);
1252 extensions.push_back(RtpExtension::kTimestampOffsetUri);
1253 TestExtensionFilter(extensions, RtpExtension::kAbsSendTimeUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001254}
1255
stefanc1aeaf02015-10-15 07:26:07 -07001256// Test support for transport sequence number header extension.
Stefan Holmer06a5e1a2016-09-02 12:36:49 +02001257TEST_F(WebRtcVideoChannel2Test, SendTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001258 TestSetSendRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07001259}
Stefan Holmer06a5e1a2016-09-02 12:36:49 +02001260TEST_F(WebRtcVideoChannel2Test, RecvTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001261 TestSetRecvRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07001262}
1263
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001264// Test support for video rotation header extension.
1265TEST_F(WebRtcVideoChannel2Test, SendVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001266 TestSetSendRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001267}
1268TEST_F(WebRtcVideoChannel2Test, RecvVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001269 TestSetRecvRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001270}
1271
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001272TEST_F(WebRtcVideoChannel2Test, IdenticalSendExtensionsDoesntRecreateStream) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001273 const int kAbsSendTimeId = 1;
1274 const int kVideoRotationId = 2;
isheriff6f8d6862016-05-26 11:24:55 -07001275 send_parameters_.extensions.push_back(
1276 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
1277 send_parameters_.extensions.push_back(
1278 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001279
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001280 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001281 FakeVideoSendStream* send_stream =
1282 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1283
1284 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001285 ASSERT_EQ(2u, send_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001286
1287 // Setting the same extensions (even if in different order) shouldn't
1288 // reallocate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001289 std::reverse(send_parameters_.extensions.begin(),
1290 send_parameters_.extensions.end());
1291 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001292
1293 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1294
1295 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001296 send_parameters_.extensions.resize(1);
1297 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001298
1299 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
1300}
1301
1302TEST_F(WebRtcVideoChannel2Test, IdenticalRecvExtensionsDoesntRecreateStream) {
1303 const int kTOffsetId = 1;
1304 const int kAbsSendTimeId = 2;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001305 const int kVideoRotationId = 3;
isheriff6f8d6862016-05-26 11:24:55 -07001306 recv_parameters_.extensions.push_back(
1307 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
1308 recv_parameters_.extensions.push_back(
1309 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
1310 recv_parameters_.extensions.push_back(
1311 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001312
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001313 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Peter Boström54be3e02015-05-25 15:04:24 +02001314 FakeVideoReceiveStream* recv_stream =
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001315 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1316
1317 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Peter Boström54be3e02015-05-25 15:04:24 +02001318 ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001319
1320 // Setting the same extensions (even if in different order) shouldn't
1321 // reallocate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001322 std::reverse(recv_parameters_.extensions.begin(),
1323 recv_parameters_.extensions.end());
1324 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001325
1326 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
1327
1328 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001329 recv_parameters_.extensions.resize(1);
1330 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001331
1332 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
1333}
1334
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001335TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001336 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001337 const int kUnsupportedId = 1;
1338 const int kTOffsetId = 2;
1339
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001340 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001341 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001342 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001343 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001344 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001345 FakeVideoSendStream* send_stream =
1346 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1347
1348 // Only timestamp offset extension is set to send stream,
1349 // unsupported rtp extension is ignored.
1350 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07001351 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
1352 send_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001353}
1354
1355TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001356 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001357 const int kUnsupportedId = 1;
1358 const int kTOffsetId = 2;
1359
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001360 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001361 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001362 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001363 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001364 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001365 FakeVideoReceiveStream* recv_stream =
1366 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1367
1368 // Only timestamp offset extension is set to receive stream,
1369 // unsupported rtp extension is ignored.
1370 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07001371 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
1372 recv_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001373}
1374
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001375TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02001376 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00001377 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07001378 send_parameters_.extensions.push_back(
1379 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001380 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001381 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1382 }
1383}
1384
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001385TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02001386 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00001387 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07001388 recv_parameters_.extensions.push_back(
1389 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001390 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001391 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1392 }
1393}
1394
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001395TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001396 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001397 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001398 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001399 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001400 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001401 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001402
1403 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001404 send_parameters_.extensions.clear();
1405 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001406 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001407 send_parameters_.extensions.push_back(send_parameters_.extensions.back());
1408 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001409}
1410
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001411TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001412 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001413 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001414 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001415 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001416 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001417 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001418
1419 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001420 recv_parameters_.extensions.clear();
1421 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001422 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001423 recv_parameters_.extensions.push_back(recv_parameters_.extensions.back());
1424 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001425}
1426
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001427TEST_F(WebRtcVideoChannel2Test, AddRecvStreamOnlyUsesOneReceiveStream) {
1428 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001429 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001430}
1431
Peter Boströmd7da1202015-06-05 14:09:38 +02001432TEST_F(WebRtcVideoChannel2Test, RtcpIsCompoundByDefault) {
1433 FakeVideoReceiveStream* stream = AddRecvStream();
pbosda903ea2015-10-02 02:36:56 -07001434 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream->GetConfig().rtp.rtcp_mode);
Peter Boströmd7da1202015-06-05 14:09:38 +02001435}
1436
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001437TEST_F(WebRtcVideoChannel2Test, RembIsEnabledByDefault) {
1438 FakeVideoReceiveStream* stream = AddRecvStream();
1439 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001440}
1441
stefan43edf0f2015-11-20 18:05:48 -08001442TEST_F(WebRtcVideoChannel2Test, TransportCcIsEnabledByDefault) {
1443 FakeVideoReceiveStream* stream = AddRecvStream();
1444 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1445}
1446
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001447TEST_F(WebRtcVideoChannel2Test, RembCanBeEnabledAndDisabled) {
1448 FakeVideoReceiveStream* stream = AddRecvStream();
1449 EXPECT_TRUE(stream->GetConfig().rtp.remb);
1450
Peter Boström126c03e2015-05-11 12:48:12 +02001451 // Verify that REMB is turned off when send(!) codecs without REMB are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001452 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001453 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001454 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1455 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001456 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001457 EXPECT_FALSE(stream->GetConfig().rtp.remb);
1458
1459 // Verify that REMB is turned on when setting default codecs since the
1460 // default codecs have REMB enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001461 parameters.codecs = engine_.codecs();
1462 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001463 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001464 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001465}
1466
stefan43edf0f2015-11-20 18:05:48 -08001467TEST_F(WebRtcVideoChannel2Test, TransportCcCanBeEnabledAndDisabled) {
1468 FakeVideoReceiveStream* stream = AddRecvStream();
1469 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1470
1471 // Verify that transport cc feedback is turned off when send(!) codecs without
1472 // transport cc feedback are set.
1473 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001474 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
stefan43edf0f2015-11-20 18:05:48 -08001475 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1476 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1477 stream = fake_call_->GetVideoReceiveStreams()[0];
1478 EXPECT_FALSE(stream->GetConfig().rtp.transport_cc);
1479
1480 // Verify that transport cc feedback is turned on when setting default codecs
1481 // since the default codecs have transport cc feedback enabled.
1482 parameters.codecs = engine_.codecs();
1483 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1484 stream = fake_call_->GetVideoReceiveStreams()[0];
1485 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1486}
1487
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001488TEST_F(WebRtcVideoChannel2Test, NackIsEnabledByDefault) {
1489 VerifyCodecHasDefaultFeedbackParams(default_codec_);
1490
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001491 cricket::VideoSendParameters parameters;
1492 parameters.codecs = engine_.codecs();
1493 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org19864742014-05-30 07:35:47 +00001494 EXPECT_TRUE(channel_->SetSend(true));
1495
1496 // Send side.
1497 FakeVideoSendStream* send_stream =
1498 AddSendStream(cricket::StreamParams::CreateLegacy(1));
1499 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1500
1501 // Receiver side.
1502 FakeVideoReceiveStream* recv_stream =
1503 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
1504 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1505
1506 // Nack history size should match between sender and receiver.
1507 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
1508 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001509}
1510
Peter Boström67c9df72015-05-11 14:34:58 +02001511TEST_F(WebRtcVideoChannel2Test, NackCanBeEnabledAndDisabled) {
Peter Boström67c9df72015-05-11 14:34:58 +02001512 FakeVideoSendStream* send_stream = AddSendStream();
Peter Boström3548dd22015-05-22 18:48:36 +02001513 FakeVideoReceiveStream* recv_stream = AddRecvStream();
Peter Boström67c9df72015-05-11 14:34:58 +02001514
1515 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1516 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1517
1518 // Verify that NACK is turned off when send(!) codecs without NACK are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001519 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001520 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001521 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1522 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02001523 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1524 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
1525 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001526 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
1527
Peter Boström67c9df72015-05-11 14:34:58 +02001528 // Verify that NACK is turned on when setting default codecs since the
1529 // default codecs have NACK enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001530 parameters.codecs = engine_.codecs();
1531 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02001532 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1533 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1534 send_stream = fake_call_->GetVideoSendStreams()[0];
1535 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001536}
1537
Peter Boströme7ba0862016-03-12 00:02:28 +01001538// This test verifies that new frame sizes reconfigures encoders even though not
1539// (yet) sending. The purpose of this is to permit encoding as quickly as
1540// possible once we start sending. Likely the frames being input are from the
1541// same source that will be sent later, which just means that we're ready
1542// earlier.
1543TEST_F(WebRtcVideoChannel2Test, ReconfiguresEncodersWhenNotSending) {
1544 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001545 parameters.codecs.push_back(GetEngineCodec("VP8"));
Peter Boströme7ba0862016-03-12 00:02:28 +01001546 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1547 channel_->SetSend(false);
1548
1549 FakeVideoSendStream* stream = AddSendStream();
1550
perkjfa10b552016-10-02 23:45:26 -07001551 // No frames entered.
Peter Boströme7ba0862016-03-12 00:02:28 +01001552 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07001553 EXPECT_EQ(0u, streams[0].width);
1554 EXPECT_EQ(0u, streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01001555
1556 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07001557 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
perkj26752742016-10-24 01:21:16 -07001558 VideoFormat capture_format = capturer.GetSupportedFormats()->front();
1559 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format));
Peter Boströme7ba0862016-03-12 00:02:28 +01001560 EXPECT_TRUE(capturer.CaptureFrame());
1561
1562 // Frame entered, should be reconfigured to new dimensions.
1563 streams = stream->GetVideoStreams();
perkj26752742016-10-24 01:21:16 -07001564 EXPECT_EQ(capture_format.width, streams[0].width);
1565 EXPECT_EQ(capture_format.height, streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01001566
deadbeef5a4a75a2016-06-02 16:23:38 -07001567 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boströme7ba0862016-03-12 00:02:28 +01001568}
1569
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001570TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) {
1571 static const int kScreenshareMinBitrateKbps = 800;
magjed509e4fe2016-11-18 01:34:11 -08001572 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001573 cricket::VideoSendParameters parameters;
1574 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001575 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001576 AddSendStream();
1577
deadbeef5a4a75a2016-06-02 16:23:38 -07001578 cricket::FakeVideoCapturer capturer;
nisse05103312016-03-16 02:22:50 -07001579 VideoOptions min_bitrate_options;
1580 min_bitrate_options.screencast_min_bitrate_kbps =
1581 rtc::Optional<int>(kScreenshareMinBitrateKbps);
deadbeef5a4a75a2016-06-02 16:23:38 -07001582 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &min_bitrate_options,
1583 &capturer));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001584 cricket::VideoFormat capture_format_hd =
1585 capturer.GetSupportedFormats()->front();
1586 EXPECT_EQ(1280, capture_format_hd.width);
1587 EXPECT_EQ(720, capture_format_hd.height);
1588 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1589
1590 EXPECT_TRUE(channel_->SetSend(true));
1591
1592 EXPECT_TRUE(capturer.CaptureFrame());
1593 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1594 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1595
1596 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1597
1598 // Verify non-screencast settings.
perkj26091b12016-09-01 01:17:40 -07001599 webrtc::VideoEncoderConfig encoder_config =
1600 send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02001601 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001602 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07001603 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
1604 EXPECT_EQ(capture_format_hd.width, streams.front().width);
1605 EXPECT_EQ(capture_format_hd.height, streams.front().height);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001606 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
1607 << "Non-screenshare shouldn't use min-transmit bitrate.";
1608
deadbeef5a4a75a2016-06-02 16:23:38 -07001609 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkj2d5f0912016-02-29 00:04:41 -08001610 // Removing a capturer triggers a black frame to be sent.
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001611 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
nisse05103312016-03-16 02:22:50 -07001612 VideoOptions screencast_options;
1613 screencast_options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001614 EXPECT_TRUE(
1615 channel_->SetVideoSend(last_ssrc_, true, &screencast_options, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08001616 EXPECT_TRUE(capturer.CaptureFrame());
Niels Möller60653ba2016-03-02 11:41:36 +01001617 // Send stream not recreated after option change.
1618 ASSERT_EQ(send_stream, fake_call_->GetVideoSendStreams().front());
perkj2d5f0912016-02-29 00:04:41 -08001619 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001620
1621 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07001622 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02001623 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001624 encoder_config.content_type);
1625 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
1626 encoder_config.min_transmit_bitrate_bps);
1627
perkjfa10b552016-10-02 23:45:26 -07001628 streams = send_stream->GetVideoStreams();
1629 EXPECT_EQ(capture_format_hd.width, streams.front().width);
1630 EXPECT_EQ(capture_format_hd.height, streams.front().height);
1631 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
deadbeef5a4a75a2016-06-02 16:23:38 -07001632 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001633}
1634
Niels Möller60653ba2016-03-02 11:41:36 +01001635TEST_F(WebRtcVideoChannel2Test, NoRecreateStreamForScreencast) {
1636 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
1637 ASSERT_TRUE(
1638 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1639 EXPECT_TRUE(channel_->SetSend(true));
1640
1641 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07001642 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001643 EXPECT_EQ(cricket::CS_RUNNING,
1644 capturer.Start(capturer.GetSupportedFormats()->front()));
1645 EXPECT_TRUE(capturer.CaptureFrame());
1646
1647 ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1648 FakeVideoSendStream* stream = fake_call_->GetVideoSendStreams().front();
perkj26091b12016-09-01 01:17:40 -07001649 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
Niels Möller60653ba2016-03-02 11:41:36 +01001650 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
1651 encoder_config.content_type);
1652
1653 EXPECT_EQ(1, stream->GetNumberOfSwappedFrames());
1654
1655 /* Switch to screencast source. We expect a reconfigure of the
1656 * encoder, but no change of the send stream. */
1657 struct VideoOptions video_options;
1658 video_options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001659 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, &video_options, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001660
1661 EXPECT_TRUE(capturer.CaptureFrame());
1662 ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1663 ASSERT_EQ(stream, fake_call_->GetVideoSendStreams().front());
1664 EXPECT_EQ(2, stream->GetNumberOfSwappedFrames());
1665
perkj26091b12016-09-01 01:17:40 -07001666 encoder_config = stream->GetEncoderConfig().Copy();
Niels Möller60653ba2016-03-02 11:41:36 +01001667 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
1668 encoder_config.content_type);
1669
1670 /* Switch back. */
1671 video_options.is_screencast = rtc::Optional<bool>(false);
deadbeef5a4a75a2016-06-02 16:23:38 -07001672 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, &video_options, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001673
1674 EXPECT_TRUE(capturer.CaptureFrame());
1675 ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1676 ASSERT_EQ(stream, fake_call_->GetVideoSendStreams().front());
1677 EXPECT_EQ(3, stream->GetNumberOfSwappedFrames());
1678
perkj26091b12016-09-01 01:17:40 -07001679 encoder_config = stream->GetEncoderConfig().Copy();
Niels Möller60653ba2016-03-02 11:41:36 +01001680 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
1681 encoder_config.content_type);
1682
deadbeef5a4a75a2016-06-02 16:23:38 -07001683 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr, nullptr));
Niels Möller60653ba2016-03-02 11:41:36 +01001684}
1685
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001686TEST_F(WebRtcVideoChannel2Test,
1687 ConferenceModeScreencastConfiguresTemporalLayer) {
Erik Språng2c4c9142015-06-24 11:24:44 +02001688 static const int kConferenceScreencastTemporalBitrateBps =
1689 ScreenshareLayerConfig::GetDefault().tl0_bitrate_kbps * 1000;
nisse4b4dc862016-02-17 05:25:36 -08001690 send_parameters_.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001691 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001692
1693 AddSendStream();
nisse05103312016-03-16 02:22:50 -07001694 VideoOptions options;
1695 options.is_screencast = rtc::Optional<bool>(true);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001696 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07001697 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001698 cricket::VideoFormat capture_format_hd =
1699 capturer.GetSupportedFormats()->front();
1700 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1701
1702 EXPECT_TRUE(channel_->SetSend(true));
1703
1704 EXPECT_TRUE(capturer.CaptureFrame());
1705 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1706 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1707
perkj26091b12016-09-01 01:17:40 -07001708 webrtc::VideoEncoderConfig encoder_config =
1709 send_stream->GetEncoderConfig().Copy();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001710
1711 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07001712 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02001713 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001714 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07001715
1716 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
1717 ASSERT_EQ(1u, streams.size());
1718 ASSERT_EQ(1u, streams[0].temporal_layer_thresholds_bps.size());
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001719 EXPECT_EQ(kConferenceScreencastTemporalBitrateBps,
perkjfa10b552016-10-02 23:45:26 -07001720 streams[0].temporal_layer_thresholds_bps[0]);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001721
deadbeef5a4a75a2016-06-02 16:23:38 -07001722 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001723}
1724
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001725TEST_F(WebRtcVideoChannel2Test, SuspendBelowMinBitrateDisabledByDefault) {
1726 FakeVideoSendStream* stream = AddSendStream();
1727 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1728}
1729
nisse0db023a2016-03-01 04:29:59 -08001730TEST_F(WebRtcVideoChannel2Test, SetMediaConfigSuspendBelowMinBitrate) {
1731 MediaConfig media_config = MediaConfig();
1732 media_config.video.suspend_below_min_bitrate = true;
1733
1734 channel_.reset(
1735 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08001736 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08001737
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001738 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001739
1740 FakeVideoSendStream* stream = AddSendStream();
1741 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
1742
nisse0db023a2016-03-01 04:29:59 -08001743 media_config.video.suspend_below_min_bitrate = false;
1744 channel_.reset(
1745 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08001746 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08001747
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001748 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001749
nisse0db023a2016-03-01 04:29:59 -08001750 stream = AddSendStream();
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001751 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1752}
1753
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001754TEST_F(WebRtcVideoChannel2Test, Vp8DenoisingEnabledByDefault) {
1755 FakeVideoSendStream* stream = AddSendStream();
1756 webrtc::VideoCodecVP8 vp8_settings;
1757 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1758 EXPECT_TRUE(vp8_settings.denoisingOn);
1759}
1760
Erik Språng143cec12015-04-28 10:01:41 +02001761TEST_F(WebRtcVideoChannel2Test, VerifyVp8SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001762 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001763 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001764 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001765
Peter Boström2feafdb2015-09-09 14:32:14 +02001766 // Single-stream settings should apply with RTX as well (verifies that we
1767 // check number of regular SSRCs and not StreamParams::ssrcs which contains
1768 // both RTX and regular SSRCs).
1769 FakeVideoSendStream* stream = SetUpSimulcast(false, true);
Erik Språng143cec12015-04-28 10:01:41 +02001770
1771 cricket::FakeVideoCapturer capturer;
Erik Språng143cec12015-04-28 10:01:41 +02001772 EXPECT_EQ(cricket::CS_RUNNING,
1773 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07001774 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik Språng143cec12015-04-28 10:01:41 +02001775 channel_->SetSend(true);
1776
1777 EXPECT_TRUE(capturer.CaptureFrame());
1778
pbos4cba4eb2015-10-26 11:18:18 -07001779 webrtc::VideoCodecVP8 vp8_settings;
1780 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1781 EXPECT_TRUE(vp8_settings.denoisingOn)
1782 << "VP8 denoising should be on by default.";
1783
nisse05103312016-03-16 02:22:50 -07001784 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001785
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001786 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1787 EXPECT_FALSE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02001788 EXPECT_TRUE(vp8_settings.automaticResizeOn);
1789 EXPECT_TRUE(vp8_settings.frameDroppingOn);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001790
nisse05103312016-03-16 02:22:50 -07001791 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001792
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001793 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1794 EXPECT_TRUE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02001795 EXPECT_TRUE(vp8_settings.automaticResizeOn);
1796 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1797
deadbeef5a4a75a2016-06-02 16:23:38 -07001798 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boström2feafdb2015-09-09 14:32:14 +02001799 stream = SetUpSimulcast(true, false);
deadbeef5a4a75a2016-06-02 16:23:38 -07001800 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik Språng143cec12015-04-28 10:01:41 +02001801 channel_->SetSend(true);
1802 EXPECT_TRUE(capturer.CaptureFrame());
1803
1804 EXPECT_EQ(3, stream->GetVideoStreams().size());
1805 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1806 // Autmatic resize off when using simulcast.
1807 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1808 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1809
1810 // In screen-share mode, denoising is forced off and simulcast disabled.
nisse05103312016-03-16 02:22:50 -07001811 VideoOptions options;
1812 options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001813 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001814
nisse05103312016-03-16 02:22:50 -07001815 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001816
1817 EXPECT_EQ(1, stream->GetVideoStreams().size());
1818 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1819 EXPECT_FALSE(vp8_settings.denoisingOn);
1820 // Resizing and frame dropping always off for screen sharing.
1821 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1822 EXPECT_FALSE(vp8_settings.frameDroppingOn);
1823
nisse05103312016-03-16 02:22:50 -07001824 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
Erik Språng143cec12015-04-28 10:01:41 +02001825
1826 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1827 EXPECT_FALSE(vp8_settings.denoisingOn);
1828 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1829 EXPECT_FALSE(vp8_settings.frameDroppingOn);
1830
deadbeef5a4a75a2016-06-02 16:23:38 -07001831 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Erik Språng143cec12015-04-28 10:01:41 +02001832}
1833
deadbeef119760a2016-04-04 11:43:27 -07001834// Test that setting the same options doesn't result in the encoder being
1835// reconfigured.
1836TEST_F(WebRtcVideoChannel2Test, SetIdenticalOptionsDoesntReconfigureEncoder) {
1837 VideoOptions options;
1838 cricket::FakeVideoCapturer capturer;
1839
perkjfa10b552016-10-02 23:45:26 -07001840 AddSendStream();
deadbeef119760a2016-04-04 11:43:27 -07001841 EXPECT_EQ(cricket::CS_RUNNING,
1842 capturer.Start(capturer.GetSupportedFormats()->front()));
perkjfa10b552016-10-02 23:45:26 -07001843 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001844 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkjfa10b552016-10-02 23:45:26 -07001845 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1846 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1847
1848 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
deadbeef5a4a75a2016-06-02 16:23:38 -07001849 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
deadbeef119760a2016-04-04 11:43:27 -07001850 EXPECT_TRUE(capturer.CaptureFrame());
perkjfa10b552016-10-02 23:45:26 -07001851 // Expect 1 reconfigurations at this point from the initial configuration.
1852 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
deadbeef119760a2016-04-04 11:43:27 -07001853
1854 // Set the options one more time and expect no additional reconfigurations.
deadbeef5a4a75a2016-06-02 16:23:38 -07001855 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
perkjfa10b552016-10-02 23:45:26 -07001856 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
1857
1858 // Change |options| and expect 2 reconfigurations.
1859 options.is_screencast = rtc::Optional<bool>(true);
1860 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
deadbeef119760a2016-04-04 11:43:27 -07001861 EXPECT_EQ(2, send_stream->num_encoder_reconfigurations());
1862
deadbeef5a4a75a2016-06-02 16:23:38 -07001863 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
deadbeef119760a2016-04-04 11:43:27 -07001864}
1865
Erik Språng143cec12015-04-28 10:01:41 +02001866class Vp9SettingsTest : public WebRtcVideoChannel2Test {
1867 public:
asaperssonc5dabdd2016-03-21 04:15:50 -07001868 Vp9SettingsTest() : Vp9SettingsTest("") {}
1869 explicit Vp9SettingsTest(const char* field_trials)
1870 : WebRtcVideoChannel2Test(field_trials) {
magjed1e45cc62016-10-28 07:43:45 -07001871 encoder_factory_.AddSupportedVideoCodecType("VP9");
Erik Språng143cec12015-04-28 10:01:41 +02001872 }
1873 virtual ~Vp9SettingsTest() {}
1874
1875 protected:
1876 void SetUp() override {
1877 engine_.SetExternalEncoderFactory(&encoder_factory_);
1878
1879 WebRtcVideoChannel2Test::SetUp();
1880 }
1881
1882 void TearDown() override {
1883 // Remove references to encoder_factory_ since this will be destroyed
1884 // before channel_ and engine_.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001885 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
Erik Språng143cec12015-04-28 10:01:41 +02001886 }
1887
1888 cricket::FakeWebRtcVideoEncoderFactory encoder_factory_;
1889};
1890
1891TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001892 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001893 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001894 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Erik Språng143cec12015-04-28 10:01:41 +02001895
Peter Boström2feafdb2015-09-09 14:32:14 +02001896 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
Erik Språng143cec12015-04-28 10:01:41 +02001897
1898 cricket::FakeVideoCapturer capturer;
Erik Språng143cec12015-04-28 10:01:41 +02001899 EXPECT_EQ(cricket::CS_RUNNING,
1900 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07001901 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik Språng143cec12015-04-28 10:01:41 +02001902 channel_->SetSend(true);
1903
1904 EXPECT_TRUE(capturer.CaptureFrame());
1905
pbos4cba4eb2015-10-26 11:18:18 -07001906 webrtc::VideoCodecVP9 vp9_settings;
1907 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1908 EXPECT_FALSE(vp9_settings.denoisingOn)
1909 << "VP9 denoising should be off by default.";
1910
nisse05103312016-03-16 02:22:50 -07001911 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001912
Erik Språng143cec12015-04-28 10:01:41 +02001913 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1914 EXPECT_FALSE(vp9_settings.denoisingOn);
1915 // Frame dropping always on for real time video.
1916 EXPECT_TRUE(vp9_settings.frameDroppingOn);
1917
nisse05103312016-03-16 02:22:50 -07001918 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
Erik Språng143cec12015-04-28 10:01:41 +02001919
1920 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1921 EXPECT_TRUE(vp9_settings.denoisingOn);
1922 EXPECT_TRUE(vp9_settings.frameDroppingOn);
1923
1924 // In screen-share mode, denoising is forced off.
nisse05103312016-03-16 02:22:50 -07001925 VideoOptions options;
1926 options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001927 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08001928
nisse05103312016-03-16 02:22:50 -07001929 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001930
1931 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1932 EXPECT_FALSE(vp9_settings.denoisingOn);
1933 // Frame dropping always off for screen sharing.
1934 EXPECT_FALSE(vp9_settings.frameDroppingOn);
1935
nisse05103312016-03-16 02:22:50 -07001936 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001937
1938 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1939 EXPECT_FALSE(vp9_settings.denoisingOn);
1940 EXPECT_FALSE(vp9_settings.frameDroppingOn);
1941
deadbeef5a4a75a2016-06-02 16:23:38 -07001942 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001943}
1944
asaperssonc5dabdd2016-03-21 04:15:50 -07001945class Vp9SettingsTestWithFieldTrial : public Vp9SettingsTest {
1946 public:
brandtr468da7c2016-11-22 02:16:47 -08001947 explicit Vp9SettingsTestWithFieldTrial(const char* field_trials)
asaperssonc5dabdd2016-03-21 04:15:50 -07001948 : Vp9SettingsTest(field_trials) {}
1949
1950 protected:
1951 void VerifySettings(int num_spatial_layers, int num_temporal_layers) {
1952 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001953 parameters.codecs.push_back(GetEngineCodec("VP9"));
asaperssonc5dabdd2016-03-21 04:15:50 -07001954 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1955
1956 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
1957
1958 cricket::FakeVideoCapturer capturer;
1959 EXPECT_EQ(cricket::CS_RUNNING,
1960 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07001961 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
asaperssonc5dabdd2016-03-21 04:15:50 -07001962 channel_->SetSend(true);
1963
1964 EXPECT_TRUE(capturer.CaptureFrame());
1965
1966 webrtc::VideoCodecVP9 vp9_settings;
1967 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1968 EXPECT_EQ(num_spatial_layers, vp9_settings.numberOfSpatialLayers);
1969 EXPECT_EQ(num_temporal_layers, vp9_settings.numberOfTemporalLayers);
1970
deadbeef5a4a75a2016-06-02 16:23:38 -07001971 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
asaperssonc5dabdd2016-03-21 04:15:50 -07001972 }
1973};
1974
1975class Vp9SettingsTestWithNoFlag : public Vp9SettingsTestWithFieldTrial {
1976 public:
1977 Vp9SettingsTestWithNoFlag() : Vp9SettingsTestWithFieldTrial("") {}
1978};
1979
1980TEST_F(Vp9SettingsTestWithNoFlag, VerifySettings) {
1981 const int kNumSpatialLayers = 1;
1982 const int kNumTemporalLayers = 1;
1983 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
1984}
1985
1986class Vp9SettingsTestWithInvalidFlag : public Vp9SettingsTestWithFieldTrial {
1987 public:
1988 Vp9SettingsTestWithInvalidFlag()
1989 : Vp9SettingsTestWithFieldTrial("WebRTC-SupportVP9SVC/Default/") {}
1990};
1991
1992TEST_F(Vp9SettingsTestWithInvalidFlag, VerifySettings) {
1993 const int kNumSpatialLayers = 1;
1994 const int kNumTemporalLayers = 1;
1995 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
1996}
1997
1998class Vp9SettingsTestWith2SL3TLFlag : public Vp9SettingsTestWithFieldTrial {
1999 public:
2000 Vp9SettingsTestWith2SL3TLFlag()
2001 : Vp9SettingsTestWithFieldTrial(
2002 "WebRTC-SupportVP9SVC/EnabledByFlag_2SL3TL/") {}
2003};
2004
2005TEST_F(Vp9SettingsTestWith2SL3TLFlag, VerifySettings) {
2006 const int kNumSpatialLayers = 2;
2007 const int kNumTemporalLayers = 3;
2008 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
2009}
2010
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002011TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruse) {
Erik Språngefbde372015-04-29 16:21:28 +02002012 TestCpuAdaptation(true, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002013}
2014
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002015TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenDisabled) {
Erik Språngefbde372015-04-29 16:21:28 +02002016 TestCpuAdaptation(false, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002017}
2018
Erik Språngefbde372015-04-29 16:21:28 +02002019TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenScreensharing) {
2020 TestCpuAdaptation(true, true);
2021}
2022
perkj2d5f0912016-02-29 00:04:41 -08002023TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruseAndChangeResolution) {
magjed509e4fe2016-11-18 01:34:11 -08002024 cricket::VideoCodec codec = GetEngineCodec("VP8");
perkj2d5f0912016-02-29 00:04:41 -08002025 cricket::VideoSendParameters parameters;
2026 parameters.codecs.push_back(codec);
2027
2028 MediaConfig media_config = MediaConfig();
2029 channel_.reset(
2030 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002031 channel_->OnReadyToSend(true);
perkj2d5f0912016-02-29 00:04:41 -08002032 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2033
2034 AddSendStream();
2035
2036 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002037 ASSERT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08002038 ASSERT_EQ(cricket::CS_RUNNING,
2039 capturer.Start(capturer.GetSupportedFormats()->front()));
2040 ASSERT_TRUE(channel_->SetSend(true));
2041
2042 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2043 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
perkj2d5f0912016-02-29 00:04:41 -08002044
2045 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2046 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2047 EXPECT_EQ(1280, send_stream->GetLastWidth());
2048 EXPECT_EQ(720, send_stream->GetLastHeight());
2049
2050 // Trigger overuse.
perkj803d97f2016-11-01 11:45:46 -07002051 rtc::VideoSinkWants wants;
2052 wants.max_pixel_count = rtc::Optional<int>(
2053 send_stream->GetLastWidth() * send_stream->GetLastHeight() - 1);
2054 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002055 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2056 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
2057 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2058 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2059
2060 // Trigger overuse again.
perkj803d97f2016-11-01 11:45:46 -07002061 wants.max_pixel_count = rtc::Optional<int>(
2062 send_stream->GetLastWidth() * send_stream->GetLastHeight() - 1);
2063 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002064 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2065 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
2066 EXPECT_EQ(1280 * 2 / 4, send_stream->GetLastWidth());
2067 EXPECT_EQ(720 * 2 / 4, send_stream->GetLastHeight());
2068
2069 // Change input resolution.
2070 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
perkj803d97f2016-11-01 11:45:46 -07002071 EXPECT_EQ(4, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002072 EXPECT_EQ(1284 / 2, send_stream->GetLastWidth());
2073 EXPECT_EQ(724 / 2, send_stream->GetLastHeight());
2074
2075 // Trigger underuse which should go back up in resolution.
perkj803d97f2016-11-01 11:45:46 -07002076 wants.max_pixel_count = rtc::Optional<int>();
2077 wants.max_pixel_count_step_up = rtc::Optional<int>(
2078 send_stream->GetLastWidth() * send_stream->GetLastHeight());
2079 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002080 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
perkj803d97f2016-11-01 11:45:46 -07002081 EXPECT_EQ(5, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002082 EXPECT_EQ(1284 * 3 / 4, send_stream->GetLastWidth());
2083 EXPECT_EQ(724 * 3 / 4, send_stream->GetLastHeight());
2084
2085 // Trigger underuse which should go back up in resolution.
perkj803d97f2016-11-01 11:45:46 -07002086 wants.max_pixel_count = rtc::Optional<int>();
2087 wants.max_pixel_count_step_up = rtc::Optional<int>(
2088 send_stream->GetLastWidth() * send_stream->GetLastHeight());
2089 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002090 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
perkj803d97f2016-11-01 11:45:46 -07002091 EXPECT_EQ(6, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002092 EXPECT_EQ(1284, send_stream->GetLastWidth());
2093 EXPECT_EQ(724, send_stream->GetLastHeight());
2094
deadbeef5a4a75a2016-06-02 16:23:38 -07002095 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkj2d5f0912016-02-29 00:04:41 -08002096}
2097
Per766ad3b2016-04-05 15:23:49 +02002098TEST_F(WebRtcVideoChannel2Test, PreviousAdaptationDoesNotApplyToScreenshare) {
magjed509e4fe2016-11-18 01:34:11 -08002099 cricket::VideoCodec codec = GetEngineCodec("VP8");
Per766ad3b2016-04-05 15:23:49 +02002100 cricket::VideoSendParameters parameters;
2101 parameters.codecs.push_back(codec);
2102
2103 MediaConfig media_config = MediaConfig();
2104 channel_.reset(
2105 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002106 channel_->OnReadyToSend(true);
Per766ad3b2016-04-05 15:23:49 +02002107 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2108
2109 AddSendStream();
2110
2111 cricket::FakeVideoCapturer capturer;
Per766ad3b2016-04-05 15:23:49 +02002112 ASSERT_EQ(cricket::CS_RUNNING,
2113 capturer.Start(capturer.GetSupportedFormats()->front()));
2114 ASSERT_TRUE(channel_->SetSend(true));
2115 cricket::VideoOptions camera_options;
perkj803d97f2016-11-01 11:45:46 -07002116 camera_options.is_screencast = rtc::Optional<bool>(false);
deadbeef5a4a75a2016-06-02 16:23:38 -07002117 channel_->SetVideoSend(last_ssrc_, true /* enable */, &camera_options,
2118 &capturer);
Per766ad3b2016-04-05 15:23:49 +02002119
2120 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2121 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
Per766ad3b2016-04-05 15:23:49 +02002122
2123 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2124 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2125 EXPECT_EQ(1280, send_stream->GetLastWidth());
2126 EXPECT_EQ(720, send_stream->GetLastHeight());
2127
2128 // Trigger overuse.
perkj803d97f2016-11-01 11:45:46 -07002129 rtc::VideoSinkWants wants;
2130 wants.max_pixel_count = rtc::Optional<int>(
2131 send_stream->GetLastWidth() * send_stream->GetLastHeight() - 1);
2132 send_stream->InjectVideoSinkWants(wants);
Per766ad3b2016-04-05 15:23:49 +02002133 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2134 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
2135 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2136 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2137
2138 // Switch to screen share. Expect no CPU adaptation.
2139 cricket::FakeVideoCapturer screen_share(true);
2140 ASSERT_EQ(cricket::CS_RUNNING,
2141 screen_share.Start(screen_share.GetSupportedFormats()->front()));
Per766ad3b2016-04-05 15:23:49 +02002142 cricket::VideoOptions screenshare_options;
2143 screenshare_options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07002144 channel_->SetVideoSend(last_ssrc_, true /* enable */, &screenshare_options,
2145 &screen_share);
Per766ad3b2016-04-05 15:23:49 +02002146 EXPECT_TRUE(screen_share.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
2147 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
2148 EXPECT_EQ(1284, send_stream->GetLastWidth());
2149 EXPECT_EQ(724, send_stream->GetLastHeight());
2150
2151 // Switch back to the normal capturer. Expect the frame to be CPU adapted.
deadbeef5a4a75a2016-06-02 16:23:38 -07002152 channel_->SetVideoSend(last_ssrc_, true /* enable */, &camera_options,
2153 &capturer);
Per766ad3b2016-04-05 15:23:49 +02002154 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2155 EXPECT_EQ(4, send_stream->GetNumberOfSwappedFrames());
2156 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2157 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2158
deadbeef5a4a75a2016-06-02 16:23:38 -07002159 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Per766ad3b2016-04-05 15:23:49 +02002160}
2161
Erik Språngefbde372015-04-29 16:21:28 +02002162void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse,
2163 bool is_screenshare) {
magjed509e4fe2016-11-18 01:34:11 -08002164 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002165 cricket::VideoSendParameters parameters;
2166 parameters.codecs.push_back(codec);
nisse51542be2016-02-12 02:27:06 -08002167
2168 MediaConfig media_config = MediaConfig();
Peter Boströme4328002015-04-14 22:45:29 +02002169 if (!enable_overuse) {
nisse0db023a2016-03-01 04:29:59 -08002170 media_config.video.enable_cpu_overuse_detection = false;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002171 }
nisse51542be2016-02-12 02:27:06 -08002172 channel_.reset(
2173 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002174 channel_->OnReadyToSend(true);
nisse51542be2016-02-12 02:27:06 -08002175
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002176 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002177
2178 AddSendStream();
2179
deadbeef5a4a75a2016-06-02 16:23:38 -07002180 cricket::FakeVideoCapturer capturer;
nisse05103312016-03-16 02:22:50 -07002181 VideoOptions options;
2182 options.is_screencast = rtc::Optional<bool>(is_screenshare);
deadbeef5a4a75a2016-06-02 16:23:38 -07002183 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
perkj26752742016-10-24 01:21:16 -07002184 cricket::VideoFormat capture_format = capturer.GetSupportedFormats()->front();
2185 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002186
2187 EXPECT_TRUE(channel_->SetSend(true));
2188
solenberge5269742015-09-08 05:13:22 -07002189 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
perkj2d5f0912016-02-29 00:04:41 -08002190
perkj803d97f2016-11-01 11:45:46 -07002191 if (!enable_overuse || is_screenshare) {
2192 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
perkj2d5f0912016-02-29 00:04:41 -08002193
2194 EXPECT_TRUE(capturer.CaptureFrame());
2195 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2196
perkj26752742016-10-24 01:21:16 -07002197 EXPECT_EQ(capture_format.width, send_stream->GetLastWidth());
2198 EXPECT_EQ(capture_format.height, send_stream->GetLastHeight());
perkj2d5f0912016-02-29 00:04:41 -08002199
deadbeef5a4a75a2016-06-02 16:23:38 -07002200 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkj2d5f0912016-02-29 00:04:41 -08002201 return;
2202 }
2203
perkj803d97f2016-11-01 11:45:46 -07002204 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
2205 // Trigger overuse.
2206 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2207
2208 rtc::VideoSinkWants wants;
2209 wants.max_pixel_count =
2210 rtc::Optional<int>(capture_format.width * capture_format.height - 1);
2211 send_stream->InjectVideoSinkWants(wants);
2212
perkj2d5f0912016-02-29 00:04:41 -08002213 EXPECT_TRUE(capturer.CaptureFrame());
2214 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002215
2216 EXPECT_TRUE(capturer.CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -08002217 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002218
perkj803d97f2016-11-01 11:45:46 -07002219 EXPECT_LT(send_stream->GetLastWidth(), capture_format.width);
2220 EXPECT_LT(send_stream->GetLastHeight(), capture_format.height);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002221
2222 // Trigger underuse which should go back to normal resolution.
perkj803d97f2016-11-01 11:45:46 -07002223 wants.max_pixel_count = rtc::Optional<int>();
2224 wants.max_pixel_count_step_up = rtc::Optional<int>(
2225 send_stream->GetLastWidth() * send_stream->GetLastHeight());
2226 send_stream->InjectVideoSinkWants(wants);
2227
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002228 EXPECT_TRUE(capturer.CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -08002229 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002230
perkj26752742016-10-24 01:21:16 -07002231 EXPECT_EQ(capture_format.width, send_stream->GetLastWidth());
2232 EXPECT_EQ(capture_format.height, send_stream->GetLastHeight());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002233
deadbeef5a4a75a2016-06-02 16:23:38 -07002234 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002235}
2236
magjedb09b6602015-10-01 03:02:44 -07002237TEST_F(WebRtcVideoChannel2Test, EstimatesNtpStartTimeCorrectly) {
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002238 // Start at last timestamp to verify that wraparounds are estimated correctly.
2239 static const uint32_t kInitialTimestamp = 0xFFFFFFFFu;
2240 static const int64_t kInitialNtpTimeMs = 1247891230;
2241 static const int kFrameOffsetMs = 20;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002242 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002243
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002244 FakeVideoReceiveStream* stream = AddRecvStream();
2245 cricket::FakeVideoRenderer renderer;
nisse08582ff2016-02-04 01:24:52 -08002246 EXPECT_TRUE(channel_->SetSink(last_ssrc_, &renderer));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002247
nisse64ec8f82016-09-27 00:17:25 -07002248 webrtc::VideoFrame video_frame(CreateBlackFrameBuffer(4, 4),
2249 kInitialTimestamp, 0,
2250 webrtc::kVideoRotation_0);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002251 // Initial NTP time is not available on the first frame, but should still be
2252 // able to be estimated.
nisseeb83a1a2016-03-21 01:27:56 -07002253 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002254
2255 EXPECT_EQ(1, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002256
2257 // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which
2258 // triggers a constant-overflow warning, hence we're calculating it explicitly
2259 // here.
2260 video_frame.set_timestamp(kFrameOffsetMs * 90 - 1);
2261 video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs);
nisseeb83a1a2016-03-21 01:27:56 -07002262 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002263
2264 EXPECT_EQ(2, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002265
2266 // Verify that NTP time has been correctly deduced.
2267 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002268 ASSERT_TRUE(channel_->GetStats(&info));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002269 ASSERT_EQ(1u, info.receivers.size());
2270 EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002271}
2272
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002273TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002274 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002275
2276 VideoCodec codec;
2277 EXPECT_TRUE(channel_->GetSendCodec(&codec));
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00002278 EXPECT_TRUE(codec.Matches(engine_.codecs()[0]));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002279
2280 // Using a RTX setup to verify that the default RTX payload type is good.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002281 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
2282 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002283 FakeVideoSendStream* stream = AddSendStream(
2284 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
perkj26091b12016-09-01 01:17:40 -07002285 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002286
2287 // Make sure NACK and FEC are enabled on the correct payload types.
2288 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
magjed509e4fe2016-11-18 01:34:11 -08002289 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
2290 EXPECT_EQ(GetEngineCodec("red").id, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002291
2292 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
2293 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
Shao Changbine62202f2015-04-21 20:24:50 +08002294 VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002295 // TODO(juberti): Check RTCP, PLI, TMMBR.
2296}
2297
brandtr468da7c2016-11-22 02:16:47 -08002298// TODO(brandtr): Remove when FlexFEC _is_ exposed by default.
2299TEST_F(WebRtcVideoChannel2Test, FlexfecCodecWithoutSsrcNotExposedByDefault) {
2300 FakeVideoSendStream* stream = AddSendStream();
2301 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2302
2303 EXPECT_EQ(-1, config.rtp.flexfec.flexfec_payload_type);
2304}
2305
2306// TODO(brandtr): Remove when FlexFEC _is_ exposed by default.
2307TEST_F(WebRtcVideoChannel2Test, FlexfecCodecWithSsrcNotExposedByDefault) {
2308 FakeVideoSendStream* stream = AddSendStream(
2309 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2310 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2311
2312 EXPECT_EQ(-1, config.rtp.flexfec.flexfec_payload_type);
2313}
2314
2315// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
2316// tests that use this test fixture into the corresponding "non-field trial"
2317// tests.
2318class WebRtcVideoChannel2FlexfecTest : public WebRtcVideoChannel2Test {
2319 public:
2320 WebRtcVideoChannel2FlexfecTest()
2321 : WebRtcVideoChannel2Test("WebRTC-FlexFEC-03/Enabled/") {}
2322};
2323
2324// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2325// by default.
2326TEST_F(WebRtcVideoChannel2FlexfecTest, SetDefaultSendCodecsWithoutSsrc) {
2327 FakeVideoSendStream* stream = AddSendStream();
2328 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2329
2330 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
2331 config.rtp.flexfec.flexfec_payload_type);
2332 EXPECT_FALSE(config.rtp.flexfec.IsCompleteAndEnabled());
2333}
2334
2335// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2336// by default.
2337TEST_F(WebRtcVideoChannel2FlexfecTest, SetDefaultSendCodecsWithSsrc) {
2338 FakeVideoSendStream* stream = AddSendStream(
2339 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2340 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2341
2342 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
2343 config.rtp.flexfec.flexfec_payload_type);
2344 EXPECT_TRUE(config.rtp.flexfec.IsCompleteAndEnabled());
2345}
2346
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002347TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002348 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002349 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002350 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002351
2352 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07002353 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002354
brandtrb5f2c3f2016-10-04 23:28:39 -07002355 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type);
2356 EXPECT_EQ(-1, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002357}
2358
brandtr468da7c2016-11-22 02:16:47 -08002359// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2360// by default.
2361TEST_F(WebRtcVideoChannel2FlexfecTest, SetSendCodecsWithoutFec) {
2362 cricket::VideoSendParameters parameters;
2363 parameters.codecs.push_back(GetEngineCodec("VP8"));
2364 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2365
2366 FakeVideoSendStream* stream = AddSendStream();
2367 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2368
2369 EXPECT_EQ(-1, config.rtp.flexfec.flexfec_payload_type);
2370}
2371
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002372TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002373 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
magjed509e4fe2016-11-18 01:34:11 -08002374 const int kUnusedPayloadType = 127;
2375 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType));
2376
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002377 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002378 cricket::VideoCodec rtx_codec(kUnusedPayloadType, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002379 parameters.codecs.push_back(rtx_codec);
2380 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002381 << "RTX codec without associated payload type should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002382}
2383
2384TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002385 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
magjed509e4fe2016-11-18 01:34:11 -08002386 const int kUnusedPayloadType1 = 126;
2387 const int kUnusedPayloadType2 = 127;
2388 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
2389 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
2390 {
2391 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
2392 kUnusedPayloadType1, GetEngineCodec("VP8").id);
2393 cricket::VideoSendParameters parameters;
2394 parameters.codecs.push_back(GetEngineCodec("VP8"));
2395 parameters.codecs.push_back(rtx_codec);
2396 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2397 }
2398 {
2399 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
2400 kUnusedPayloadType1, kUnusedPayloadType2);
2401 cricket::VideoSendParameters parameters;
2402 parameters.codecs.push_back(GetEngineCodec("VP8"));
2403 parameters.codecs.push_back(rtx_codec);
2404 EXPECT_FALSE(channel_->SetSendParameters(parameters))
2405 << "RTX without matching video codec should be rejected.";
2406 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002407}
2408
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002409TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002410 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002411 parameters.codecs.push_back(GetEngineCodec("VP8"));
2412 parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002413 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002414
2415 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07002416 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002417
magjed509e4fe2016-11-18 01:34:11 -08002418 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002419
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002420 parameters.codecs.pop_back();
2421 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002422 stream = fake_call_->GetVideoSendStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08002423 ASSERT_TRUE(stream != nullptr);
perkj26091b12016-09-01 01:17:40 -07002424 config = stream->GetConfig().Copy();
brandtrb5f2c3f2016-10-04 23:28:39 -07002425 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08002426 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
2427}
2428
2429// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2430// by default.
2431TEST_F(WebRtcVideoChannel2FlexfecTest, SetSendCodecsWithoutFecDisablesFec) {
2432 cricket::VideoSendParameters parameters;
2433 parameters.codecs.push_back(GetEngineCodec("VP8"));
2434 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2435 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2436
2437 FakeVideoSendStream* stream = AddSendStream(
2438 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2439 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2440
2441 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
2442 config.rtp.flexfec.flexfec_payload_type);
2443 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.flexfec_ssrc);
2444 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
2445 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
2446
2447 parameters.codecs.pop_back();
2448 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2449 stream = fake_call_->GetVideoSendStreams()[0];
2450 ASSERT_TRUE(stream != nullptr);
2451 config = stream->GetConfig().Copy();
2452 EXPECT_EQ(-1, config.rtp.flexfec.flexfec_payload_type)
2453 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002454}
2455
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002456TEST_F(WebRtcVideoChannel2Test, SetSendCodecsChangesExistingStreams) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002457 cricket::VideoSendParameters parameters;
perkj26752742016-10-24 01:21:16 -07002458 cricket::VideoCodec codec(100, "VP8");
2459 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax);
2460 parameters.codecs.push_back(codec);
perkjfa10b552016-10-02 23:45:26 -07002461
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002462 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002463 channel_->SetSend(true);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002464
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002465 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002466 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002467 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002468
2469 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07002470 EXPECT_EQ(kDefaultQpMax, streams[0].max_qp);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002471
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002472 parameters.codecs.clear();
perkj26752742016-10-24 01:21:16 -07002473 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax + 1);
2474 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002475 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002476 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07002477 EXPECT_EQ(kDefaultQpMax + 1, streams[0].max_qp);
deadbeef5a4a75a2016-06-02 16:23:38 -07002478 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002479}
2480
pbos@webrtc.org00873182014-11-25 14:03:34 +00002481TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithBitrates) {
2482 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
2483 200000);
2484}
2485
pbos@webrtc.orga5f6fb52015-03-23 22:29:39 +00002486TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithHighMaxBitrate) {
2487 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
2488 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
2489 ASSERT_EQ(1u, streams.size());
2490 EXPECT_EQ(10000000, streams[0].max_bitrate_bps);
2491}
2492
pbos@webrtc.org00873182014-11-25 14:03:34 +00002493TEST_F(WebRtcVideoChannel2Test,
2494 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
2495 SetSendCodecsShouldWorkForBitrates(
2496 "", 0, "", -1, "", -1);
2497}
2498
2499TEST_F(WebRtcVideoChannel2Test, SetSendCodecsCapsMinAndStartBitrate) {
2500 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002501}
2502
2503TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectsMaxLessThanMinBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002504 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "300";
2505 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "200";
2506 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002507}
2508
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07002509// Test that when both the codec-specific bitrate params and max_bandwidth_bps
2510// are present in the same send parameters, the settings are combined correctly.
2511TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithBitratesAndMaxSendBandwidth) {
2512 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
2513 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
2514 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
2515 send_parameters_.max_bandwidth_bps = 400000;
2516 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2517 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2518 EXPECT_EQ(200000, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2519 // We expect max_bandwidth_bps to take priority, if set.
2520 EXPECT_EQ(400000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2521
2522 // Decrease max_bandwidth_bps.
2523 send_parameters_.max_bandwidth_bps = 350000;
2524 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2525 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2526 // Since the codec isn't changing, start_bitrate_bps should be -1.
2527 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2528 EXPECT_EQ(350000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2529
2530 // Now try again with the values flipped around.
2531 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
2532 send_parameters_.max_bandwidth_bps = 300000;
2533 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2534 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2535 EXPECT_EQ(200000, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2536 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2537
2538 // If we change the codec max, max_bandwidth_bps should still apply.
2539 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
2540 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2541 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2542 EXPECT_EQ(200000, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2543 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2544}
2545
pbos@webrtc.org00873182014-11-25 14:03:34 +00002546TEST_F(WebRtcVideoChannel2Test,
2547 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
2548 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
2549 200000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002550 send_parameters_.max_bandwidth_bps = 300000;
2551 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01002552 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002553 << "Setting max bitrate should keep previous min bitrate.";
Stefan Holmere5904162015-03-26 11:11:06 +01002554 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.start_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002555 << "Setting max bitrate should not reset start bitrate.";
Stefan Holmere5904162015-03-26 11:11:06 +01002556 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002557}
2558
2559TEST_F(WebRtcVideoChannel2Test, SetMaxSendBandwidthShouldBeRemovable) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002560 send_parameters_.max_bandwidth_bps = 300000;
2561 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01002562 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002563 // <= 0 means disable (infinite) max bitrate.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002564 send_parameters_.max_bandwidth_bps = 0;
2565 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01002566 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.max_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002567 << "Setting zero max bitrate did not reset start bitrate.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002568}
2569
perkjfa10b552016-10-02 23:45:26 -07002570TEST_F(WebRtcVideoChannel2Test, SetMaxSendBandwidthAndAddSendStream) {
2571 send_parameters_.max_bandwidth_bps = 99999;
2572 FakeVideoSendStream* stream = AddSendStream();
2573 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
2574 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
2575 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2576 ASSERT_EQ(1u, stream->GetVideoStreams().size());
2577 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
2578 stream->GetVideoStreams()[0].max_bitrate_bps);
2579
2580 send_parameters_.max_bandwidth_bps = 77777;
2581 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
2582 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
2583 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2584 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
2585 stream->GetVideoStreams()[0].max_bitrate_bps);
2586}
2587
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002588TEST_F(WebRtcVideoChannel2Test, SetMaxSendBitrateCanIncreaseSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002589 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002590 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002591 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002592 channel_->SetSend(true);
2593
2594 FakeVideoSendStream* stream = AddSendStream();
2595
Peter Boström3afc8c42016-01-27 16:45:21 +01002596 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002597 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Peter Boström3afc8c42016-01-27 16:45:21 +01002598 EXPECT_EQ(cricket::CS_RUNNING,
2599 capturer.Start(capturer.GetSupportedFormats()->front()));
2600
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002601 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
2602 int initial_max_bitrate_bps = streams[0].max_bitrate_bps;
2603 EXPECT_GT(initial_max_bitrate_bps, 0);
2604
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002605 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
2606 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01002607 // Insert a frame to update the encoder config.
2608 EXPECT_TRUE(capturer.CaptureFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002609 streams = stream->GetVideoStreams();
2610 EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps);
deadbeef5a4a75a2016-06-02 16:23:38 -07002611 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002612}
2613
2614TEST_F(WebRtcVideoChannel2Test,
2615 SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002616 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002617 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002618 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002619 channel_->SetSend(true);
2620
2621 FakeVideoSendStream* stream = AddSendStream(
2622 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
2623
2624 // Send a frame to make sure this scales up to >1 stream (simulcast).
2625 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002626 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], true, nullptr, &capturer));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002627 EXPECT_EQ(cricket::CS_RUNNING,
2628 capturer.Start(capturer.GetSupportedFormats()->front()));
2629 EXPECT_TRUE(capturer.CaptureFrame());
2630
2631 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
2632 ASSERT_GT(streams.size(), 1u)
2633 << "Without simulcast this test doesn't make sense.";
pbosbe16f792015-10-16 12:49:39 -07002634 int initial_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002635 EXPECT_GT(initial_max_bitrate_bps, 0);
2636
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002637 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
2638 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01002639 // Insert a frame to update the encoder config.
2640 EXPECT_TRUE(capturer.CaptureFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002641 streams = stream->GetVideoStreams();
pbosbe16f792015-10-16 12:49:39 -07002642 int increased_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002643 EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps);
2644
deadbeef5a4a75a2016-06-02 16:23:38 -07002645 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], true, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002646}
2647
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002648TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMaxQuantization) {
2649 static const char* kMaxQuantization = "21";
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002650 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002651 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002652 parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
2653 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00002654 EXPECT_EQ(static_cast<unsigned int>(atoi(kMaxQuantization)),
2655 AddSendStream()->GetVideoStreams().back().max_qp);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002656
2657 VideoCodec codec;
2658 EXPECT_TRUE(channel_->GetSendCodec(&codec));
2659 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
2660}
2661
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002662TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) {
2663 // TODO(pbos): Should we only allow the dynamic range?
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002664 static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002665 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002666 parameters.codecs.push_back(GetEngineCodec("VP8"));
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002667 for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002668 parameters.codecs[0].id = kIncorrectPayloads[i];
2669 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pkasting@chromium.orgd3245462015-02-23 21:28:22 +00002670 << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002671 }
2672}
2673
2674TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptAllValidPayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002675 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002676 parameters.codecs.push_back(GetEngineCodec("VP8"));
magjedf823ede2016-11-12 09:53:04 -08002677 for (int payload_type = 96; payload_type <= 127; ++payload_type) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002678 parameters.codecs[0].id = payload_type;
2679 EXPECT_TRUE(channel_->SetSendParameters(parameters))
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002680 << "Payload type '" << payload_type << "' rejected.";
2681 }
2682}
2683
deadbeef67cf2c12016-04-13 10:07:16 -07002684// Test that setting the a different set of codecs but with an identical front
2685// codec doesn't result in the stream being recreated.
2686// This may happen when a subsequent negotiation includes fewer codecs, as a
2687// result of one of the codecs being rejected.
2688TEST_F(WebRtcVideoChannel2Test,
2689 SetSendCodecsIdenticalFirstCodecDoesntRecreateStream) {
2690 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08002691 parameters1.codecs.push_back(GetEngineCodec("VP8"));
2692 parameters1.codecs.push_back(GetEngineCodec("VP9"));
deadbeef67cf2c12016-04-13 10:07:16 -07002693 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
2694
2695 AddSendStream();
2696 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2697
2698 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08002699 parameters2.codecs.push_back(GetEngineCodec("VP8"));
deadbeef67cf2c12016-04-13 10:07:16 -07002700 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
2701 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2702}
2703
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002704TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithOnlyVp8) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002705 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002706 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002707 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002708}
2709
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002710// Test that we set our inbound RTX codecs properly.
2711TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithRtx) {
magjed509e4fe2016-11-18 01:34:11 -08002712 const int kUnusedPayloadType1 = 126;
2713 const int kUnusedPayloadType2 = 127;
2714 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
2715 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
2716
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002717 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002718 parameters.codecs.push_back(GetEngineCodec("VP8"));
2719 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002720 parameters.codecs.push_back(rtx_codec);
2721 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002722 << "RTX codec without associated payload should be rejected.";
2723
magjed509e4fe2016-11-18 01:34:11 -08002724 parameters.codecs[1].SetParam("apt", kUnusedPayloadType2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002725 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002726 << "RTX codec with invalid associated payload type should be rejected.";
2727
magjed509e4fe2016-11-18 01:34:11 -08002728 parameters.codecs[1].SetParam("apt", GetEngineCodec("VP8").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002729 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002730
magjed509e4fe2016-11-18 01:34:11 -08002731 cricket::VideoCodec rtx_codec2(kUnusedPayloadType2, "rtx");
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002732 rtx_codec2.SetParam("apt", rtx_codec.id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002733 parameters.codecs.push_back(rtx_codec2);
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002734
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002735 EXPECT_FALSE(channel_->SetRecvParameters(parameters)) <<
2736 "RTX codec with another RTX as associated payload type should be "
2737 "rejected.";
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002738}
2739
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002740TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentPayloadType) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002741 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002742 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002743 parameters.codecs[0].id = 99;
2744 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002745}
2746
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00002747TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsAcceptDefaultCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002748 cricket::VideoRecvParameters parameters;
2749 parameters.codecs = engine_.codecs();
2750 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00002751
2752 FakeVideoReceiveStream* stream = AddRecvStream();
Tommi733b5472016-06-10 17:58:01 +02002753 const webrtc::VideoReceiveStream::Config& config = stream->GetConfig();
pbos@webrtc.org776e6f22014-10-29 15:28:39 +00002754 EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].payload_name);
2755 EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002756}
2757
2758TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002759 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002760 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj26752742016-10-24 01:21:16 -07002761 parameters.codecs.push_back(VideoCodec(101, "WTF3"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002762 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002763}
2764
2765// TODO(pbos): Enable VP9 through external codec support
2766TEST_F(WebRtcVideoChannel2Test,
2767 DISABLED_SetRecvCodecsAcceptsMultipleVideoCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002768 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002769 parameters.codecs.push_back(GetEngineCodec("VP8"));
2770 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002771 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002772}
2773
2774TEST_F(WebRtcVideoChannel2Test,
2775 DISABLED_SetRecvCodecsSetsFecForAllVideoCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002776 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002777 parameters.codecs.push_back(GetEngineCodec("VP8"));
2778 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002779 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002780 FAIL(); // TODO(pbos): Verify that the FEC parameters are set for all codecs.
2781}
2782
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002783TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002784 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08002785 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
2786 send_parameters.codecs.push_back(GetEngineCodec("red"));
2787 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002788 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002789
2790 FakeVideoReceiveStream* stream = AddRecvStream();
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002791
magjed509e4fe2016-11-18 01:34:11 -08002792 EXPECT_EQ(GetEngineCodec("ulpfec").id,
brandtrb5f2c3f2016-10-04 23:28:39 -07002793 stream->GetConfig().rtp.ulpfec.ulpfec_payload_type);
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002794
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002795 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08002796 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002797 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002798 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08002799 ASSERT_TRUE(stream != nullptr);
brandtrb5f2c3f2016-10-04 23:28:39 -07002800 EXPECT_EQ(-1, stream->GetConfig().rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08002801 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
2802}
2803
2804// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2805// by default.
2806TEST_F(WebRtcVideoChannel2FlexfecTest, SetRecvParamsWithoutFecDisablesFec) {
2807 cricket::VideoSendParameters send_parameters;
2808 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
2809 send_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2810 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
2811
2812 AddRecvStream(
2813 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2814 const std::list<FakeFlexfecReceiveStream>& streams =
2815 fake_call_->GetFlexfecReceiveStreams();
2816
2817 ASSERT_EQ(1U, streams.size());
2818 const FakeFlexfecReceiveStream& stream = streams.front();
2819 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
2820 stream.GetConfig().flexfec_payload_type);
2821 EXPECT_EQ(kFlexfecSsrc, stream.GetConfig().flexfec_ssrc);
2822 ASSERT_EQ(1U, stream.GetConfig().protected_media_ssrcs.size());
2823 EXPECT_EQ(kSsrcs1[0], stream.GetConfig().protected_media_ssrcs[0]);
2824
2825 cricket::VideoRecvParameters recv_parameters;
2826 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
2827 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
2828 EXPECT_TRUE(streams.empty())
2829 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002830}
2831
brandtre6f98c72016-11-11 03:28:30 -08002832TEST_F(WebRtcVideoChannel2Test, SetSendParamsWithFecEnablesFec) {
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002833 FakeVideoReceiveStream* stream = AddRecvStream();
magjed509e4fe2016-11-18 01:34:11 -08002834 EXPECT_EQ(GetEngineCodec("ulpfec").id,
brandtrb5f2c3f2016-10-04 23:28:39 -07002835 stream->GetConfig().rtp.ulpfec.ulpfec_payload_type);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002836
2837 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08002838 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
2839 recv_parameters.codecs.push_back(GetEngineCodec("red"));
2840 recv_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002841 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
2842 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08002843 ASSERT_TRUE(stream != nullptr);
magjed509e4fe2016-11-18 01:34:11 -08002844 EXPECT_EQ(GetEngineCodec("ulpfec").id,
2845 stream->GetConfig().rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08002846 << "ULPFEC should be enabled on the receive stream.";
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002847
2848 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08002849 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
2850 send_parameters.codecs.push_back(GetEngineCodec("red"));
2851 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002852 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
2853 stream = fake_call_->GetVideoReceiveStreams()[0];
magjed509e4fe2016-11-18 01:34:11 -08002854 EXPECT_EQ(GetEngineCodec("ulpfec").id,
2855 stream->GetConfig().rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08002856 << "ULPFEC should be enabled on the receive stream.";
2857}
2858
2859// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2860// by default.
2861TEST_F(WebRtcVideoChannel2FlexfecTest, SetSendParamsWithFecEnablesFec) {
2862 AddRecvStream(
2863 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2864 const std::list<FakeFlexfecReceiveStream>& streams =
2865 fake_call_->GetFlexfecReceiveStreams();
2866
2867 cricket::VideoRecvParameters recv_parameters;
2868 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
2869 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2870 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
2871 ASSERT_EQ(1U, streams.size());
2872 const FakeFlexfecReceiveStream& stream_with_recv_params = streams.front();
2873 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
2874 stream_with_recv_params.GetConfig().flexfec_payload_type);
2875 EXPECT_EQ(kFlexfecSsrc, stream_with_recv_params.GetConfig().flexfec_ssrc);
2876 EXPECT_EQ(1U,
2877 stream_with_recv_params.GetConfig().protected_media_ssrcs.size());
2878 EXPECT_EQ(kSsrcs1[0],
2879 stream_with_recv_params.GetConfig().protected_media_ssrcs[0]);
2880
2881 cricket::VideoSendParameters send_parameters;
2882 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
2883 send_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2884 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
2885 ASSERT_EQ(1U, streams.size());
2886 const FakeFlexfecReceiveStream& stream_with_send_params = streams.front();
2887 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
2888 stream_with_send_params.GetConfig().flexfec_payload_type);
2889 EXPECT_EQ(kFlexfecSsrc, stream_with_send_params.GetConfig().flexfec_ssrc);
2890 EXPECT_EQ(1U,
2891 stream_with_send_params.GetConfig().protected_media_ssrcs.size());
2892 EXPECT_EQ(kSsrcs1[0],
2893 stream_with_send_params.GetConfig().protected_media_ssrcs[0]);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002894}
2895
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002896TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectDuplicateFecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002897 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002898 parameters.codecs.push_back(GetEngineCodec("VP8"));
2899 parameters.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002900 parameters.codecs[1].id = parameters.codecs[0].id;
2901 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002902}
2903
brandtr468da7c2016-11-22 02:16:47 -08002904// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2905// by default.
2906TEST_F(WebRtcVideoChannel2FlexfecTest,
2907 SetSendCodecsRejectDuplicateFecPayloads) {
2908 cricket::VideoRecvParameters parameters;
2909 parameters.codecs.push_back(GetEngineCodec("VP8"));
2910 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2911 parameters.codecs[1].id = parameters.codecs[0].id;
2912 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
2913}
2914
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002915TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectDuplicateCodecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002916 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002917 parameters.codecs.push_back(GetEngineCodec("VP8"));
2918 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002919 parameters.codecs[1].id = parameters.codecs[0].id;
2920 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002921}
2922
2923TEST_F(WebRtcVideoChannel2Test,
2924 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002925 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002926 parameters.codecs.push_back(GetEngineCodec("VP8"));
2927 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002928 parameters.codecs[1].id += 1;
2929 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002930}
2931
deadbeef67cf2c12016-04-13 10:07:16 -07002932// Test that setting the same codecs but with a different order
deadbeef874ca3a2015-08-20 17:19:20 -07002933// doesn't result in the stream being recreated.
2934TEST_F(WebRtcVideoChannel2Test,
deadbeef67cf2c12016-04-13 10:07:16 -07002935 SetRecvCodecsDifferentOrderDoesntRecreateStream) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002936 cricket::VideoRecvParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08002937 parameters1.codecs.push_back(GetEngineCodec("VP8"));
2938 parameters1.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002939 EXPECT_TRUE(channel_->SetRecvParameters(parameters1));
deadbeef874ca3a2015-08-20 17:19:20 -07002940
2941 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2942 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2943
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002944 cricket::VideoRecvParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08002945 parameters2.codecs.push_back(GetEngineCodec("red"));
2946 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002947 EXPECT_TRUE(channel_->SetRecvParameters(parameters2));
deadbeef874ca3a2015-08-20 17:19:20 -07002948 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2949}
2950
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002951TEST_F(WebRtcVideoChannel2Test, SendStreamNotSendingByDefault) {
2952 EXPECT_FALSE(AddSendStream()->IsSending());
2953}
2954
pbos@webrtc.org85f42942014-07-22 09:14:58 +00002955TEST_F(WebRtcVideoChannel2Test, ReceiveStreamReceivingByDefault) {
2956 EXPECT_TRUE(AddRecvStream()->IsReceiving());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002957}
2958
2959TEST_F(WebRtcVideoChannel2Test, SetSend) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +00002960 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002961 EXPECT_FALSE(stream->IsSending());
2962
2963 // false->true
2964 EXPECT_TRUE(channel_->SetSend(true));
2965 EXPECT_TRUE(stream->IsSending());
2966 // true->true
2967 EXPECT_TRUE(channel_->SetSend(true));
2968 EXPECT_TRUE(stream->IsSending());
2969 // true->false
2970 EXPECT_TRUE(channel_->SetSend(false));
2971 EXPECT_FALSE(stream->IsSending());
2972 // false->false
2973 EXPECT_TRUE(channel_->SetSend(false));
2974 EXPECT_FALSE(stream->IsSending());
2975
2976 EXPECT_TRUE(channel_->SetSend(true));
2977 FakeVideoSendStream* new_stream = AddSendStream();
2978 EXPECT_TRUE(new_stream->IsSending())
2979 << "Send stream created after SetSend(true) not sending initially.";
2980}
2981
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00002982// This test verifies DSCP settings are properly applied on video media channel.
2983TEST_F(WebRtcVideoChannel2Test, TestSetDscpOptions) {
kwiberg686a8ef2016-02-26 03:00:35 -08002984 std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00002985 new cricket::FakeNetworkInterface);
nisse51542be2016-02-12 02:27:06 -08002986 MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002987 std::unique_ptr<VideoMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002988
2989 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
2990 channel->SetInterface(network_interface.get());
2991 // Default value when DSCP is disabled should be DSCP_DEFAULT.
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00002992 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
nisse51542be2016-02-12 02:27:06 -08002993
2994 config.enable_dscp = true;
2995 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
2996 channel->SetInterface(network_interface.get());
2997 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
2998
2999 // Verify that setting the option to false resets the
3000 // DiffServCodePoint.
3001 config.enable_dscp = false;
3002 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
3003 channel->SetInterface(network_interface.get());
3004 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003005}
3006
deadbeef13871492015-12-09 12:37:51 -08003007// This test verifies that the RTCP reduced size mode is properly applied to
3008// send video streams.
3009TEST_F(WebRtcVideoChannel2Test, TestSetSendRtcpReducedSize) {
3010 // Create stream, expecting that default mode is "compound".
3011 FakeVideoSendStream* stream1 = AddSendStream();
3012 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
3013
3014 // Now enable reduced size mode.
3015 send_parameters_.rtcp.reduced_size = true;
3016 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3017 stream1 = fake_call_->GetVideoSendStreams()[0];
3018 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
3019
3020 // Create a new stream and ensure it picks up the reduced size mode.
3021 FakeVideoSendStream* stream2 = AddSendStream();
3022 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
3023}
3024
3025// This test verifies that the RTCP reduced size mode is properly applied to
3026// receive video streams.
3027TEST_F(WebRtcVideoChannel2Test, TestSetRecvRtcpReducedSize) {
3028 // Create stream, expecting that default mode is "compound".
3029 FakeVideoReceiveStream* stream1 = AddRecvStream();
3030 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
3031
3032 // Now enable reduced size mode.
Taylor Brandstetter5f0b83b2016-03-18 15:02:07 -07003033 // TODO(deadbeef): Once "recv_parameters" becomes "receiver_parameters",
3034 // the reduced_size flag should come from that.
3035 send_parameters_.rtcp.reduced_size = true;
3036 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
deadbeef13871492015-12-09 12:37:51 -08003037 stream1 = fake_call_->GetVideoReceiveStreams()[0];
3038 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
3039
3040 // Create a new stream and ensure it picks up the reduced size mode.
3041 FakeVideoReceiveStream* stream2 = AddRecvStream();
3042 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
3043}
3044
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003045TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) {
skvlad7a43d252016-03-22 15:32:27 -07003046 EXPECT_EQ(webrtc::kNetworkUp,
3047 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
3048 EXPECT_EQ(webrtc::kNetworkUp,
3049 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003050
3051 channel_->OnReadyToSend(false);
skvlad7a43d252016-03-22 15:32:27 -07003052 EXPECT_EQ(webrtc::kNetworkDown,
3053 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
3054 EXPECT_EQ(webrtc::kNetworkUp,
3055 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003056
3057 channel_->OnReadyToSend(true);
skvlad7a43d252016-03-22 15:32:27 -07003058 EXPECT_EQ(webrtc::kNetworkUp,
3059 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
3060 EXPECT_EQ(webrtc::kNetworkUp,
3061 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003062}
3063
Peter Boström74d9ed72015-03-26 16:28:31 +01003064TEST_F(WebRtcVideoChannel2Test, GetStatsReportsSentCodecName) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003065 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003066 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003067 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström74d9ed72015-03-26 16:28:31 +01003068
3069 AddSendStream();
3070
3071 cricket::VideoMediaInfo info;
3072 ASSERT_TRUE(channel_->GetStats(&info));
magjed509e4fe2016-11-18 01:34:11 -08003073 EXPECT_EQ("VP8", info.senders[0].codec_name);
Peter Boström74d9ed72015-03-26 16:28:31 +01003074}
3075
Peter Boströmb7d9a972015-12-18 16:01:11 +01003076TEST_F(WebRtcVideoChannel2Test, GetStatsReportsEncoderImplementationName) {
3077 FakeVideoSendStream* stream = AddSendStream();
3078 webrtc::VideoSendStream::Stats stats;
3079 stats.encoder_implementation_name = "encoder_implementation_name";
3080 stream->SetStats(stats);
3081
3082 cricket::VideoMediaInfo info;
3083 ASSERT_TRUE(channel_->GetStats(&info));
3084 EXPECT_EQ(stats.encoder_implementation_name,
3085 info.senders[0].encoder_implementation_name);
3086}
3087
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00003088TEST_F(WebRtcVideoChannel2Test, GetStatsReportsCpuOveruseMetrics) {
3089 FakeVideoSendStream* stream = AddSendStream();
3090 webrtc::VideoSendStream::Stats stats;
3091 stats.avg_encode_time_ms = 13;
3092 stats.encode_usage_percent = 42;
3093 stream->SetStats(stats);
3094
3095 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003096 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00003097 EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
3098 EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
3099}
3100
sakal43536c32016-10-24 01:46:43 -07003101TEST_F(WebRtcVideoChannel2Test, GetStatsReportsFramesEncoded) {
3102 FakeVideoSendStream* stream = AddSendStream();
3103 webrtc::VideoSendStream::Stats stats;
3104 stats.frames_encoded = 13;
3105 stream->SetStats(stats);
3106
3107 cricket::VideoMediaInfo info;
3108 ASSERT_TRUE(channel_->GetStats(&info));
3109 EXPECT_EQ(stats.frames_encoded, info.senders[0].frames_encoded);
3110}
3111
sakal87da4042016-10-31 06:53:47 -07003112TEST_F(WebRtcVideoChannel2Test, GetStatsReportsQpSum) {
3113 FakeVideoSendStream* stream = AddSendStream();
3114 webrtc::VideoSendStream::Stats stats;
3115 stats.qp_sum = rtc::Optional<uint64_t>(13);
3116 stream->SetStats(stats);
3117
3118 cricket::VideoMediaInfo info;
3119 ASSERT_TRUE(channel_->GetStats(&info));
3120 EXPECT_EQ(stats.qp_sum, info.senders[0].qp_sum);
3121}
3122
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003123TEST_F(WebRtcVideoChannel2Test, GetStatsReportsUpperResolution) {
3124 FakeVideoSendStream* stream = AddSendStream();
3125 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003126 stats.substreams[17].width = 123;
3127 stats.substreams[17].height = 40;
3128 stats.substreams[42].width = 80;
3129 stats.substreams[42].height = 31;
3130 stats.substreams[11].width = 20;
3131 stats.substreams[11].height = 90;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003132 stream->SetStats(stats);
3133
3134 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003135 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003136 ASSERT_EQ(1u, info.senders.size());
3137 EXPECT_EQ(123, info.senders[0].send_frame_width);
3138 EXPECT_EQ(90, info.senders[0].send_frame_height);
3139}
3140
Pera48ddb72016-09-29 11:48:50 +02003141TEST_F(WebRtcVideoChannel2Test, GetStatsReportsPreferredBitrate) {
3142 FakeVideoSendStream* stream = AddSendStream();
3143 webrtc::VideoSendStream::Stats stats;
3144 stats.preferred_media_bitrate_bps = 5;
3145 stream->SetStats(stats);
3146
3147 cricket::VideoMediaInfo info;
3148 ASSERT_TRUE(channel_->GetStats(&info));
3149 ASSERT_EQ(1u, info.senders.size());
3150 EXPECT_EQ(5, info.senders[0].preferred_bitrate);
3151}
3152
perkj803d97f2016-11-01 11:45:46 -07003153TEST_F(WebRtcVideoChannel2Test, GetStatsReportsCpuAdaptationStats) {
3154 FakeVideoSendStream* stream = AddSendStream();
3155 webrtc::VideoSendStream::Stats stats;
3156 stats.number_of_cpu_adapt_changes = 2;
3157 stats.cpu_limited_resolution = true;
3158 stream->SetStats(stats);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003159
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003160 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003161 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003162 ASSERT_EQ(1U, info.senders.size());
Per766ad3b2016-04-05 15:23:49 +02003163 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_CPU, info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07003164 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003165}
3166
perkj803d97f2016-11-01 11:45:46 -07003167TEST_F(WebRtcVideoChannel2Test, GetStatsReportsAdaptationAndBandwidthStats) {
3168 FakeVideoSendStream* stream = AddSendStream();
asapersson17821db2015-12-14 02:08:12 -08003169 webrtc::VideoSendStream::Stats stats;
perkj803d97f2016-11-01 11:45:46 -07003170 stats.number_of_cpu_adapt_changes = 2;
3171 stats.cpu_limited_resolution = true;
asapersson17821db2015-12-14 02:08:12 -08003172 stats.bw_limited_resolution = true;
perkj803d97f2016-11-01 11:45:46 -07003173 stream->SetStats(stats);
3174
3175 cricket::VideoMediaInfo info;
asapersson17821db2015-12-14 02:08:12 -08003176 EXPECT_TRUE(channel_->GetStats(&info));
3177 ASSERT_EQ(1U, info.senders.size());
Per766ad3b2016-04-05 15:23:49 +02003178 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_CPU |
3179 WebRtcVideoChannel2::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08003180 info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07003181 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
asapersson17821db2015-12-14 02:08:12 -08003182}
3183
3184TEST_F(WebRtcVideoChannel2Test,
3185 GetStatsTranslatesBandwidthLimitedResolutionCorrectly) {
3186 FakeVideoSendStream* stream = AddSendStream();
3187 webrtc::VideoSendStream::Stats stats;
3188 stats.bw_limited_resolution = true;
3189 stream->SetStats(stats);
3190
3191 cricket::VideoMediaInfo info;
3192 EXPECT_TRUE(channel_->GetStats(&info));
3193 ASSERT_EQ(1U, info.senders.size());
Per766ad3b2016-04-05 15:23:49 +02003194 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08003195 info.senders[0].adapt_reason);
3196}
3197
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003198TEST_F(WebRtcVideoChannel2Test,
3199 GetStatsTranslatesSendRtcpPacketTypesCorrectly) {
3200 FakeVideoSendStream* stream = AddSendStream();
3201 webrtc::VideoSendStream::Stats stats;
3202 stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2;
3203 stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3;
3204 stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4;
3205
3206 stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5;
3207 stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7;
3208 stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9;
3209
3210 stream->SetStats(stats);
3211
3212 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003213 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003214 EXPECT_EQ(7, info.senders[0].firs_rcvd);
3215 EXPECT_EQ(10, info.senders[0].nacks_rcvd);
3216 EXPECT_EQ(13, info.senders[0].plis_rcvd);
3217}
3218
3219TEST_F(WebRtcVideoChannel2Test,
3220 GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) {
3221 FakeVideoReceiveStream* stream = AddRecvStream();
3222 webrtc::VideoReceiveStream::Stats stats;
3223 stats.rtcp_packet_type_counts.fir_packets = 2;
3224 stats.rtcp_packet_type_counts.nack_packets = 3;
3225 stats.rtcp_packet_type_counts.pli_packets = 4;
3226 stream->SetStats(stats);
3227
3228 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003229 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003230 EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets,
3231 info.receivers[0].firs_sent);
3232 EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets,
3233 info.receivers[0].nacks_sent);
3234 EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets,
3235 info.receivers[0].plis_sent);
3236}
3237
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003238TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesDecodeStatsCorrectly) {
3239 FakeVideoReceiveStream* stream = AddRecvStream();
3240 webrtc::VideoReceiveStream::Stats stats;
Peter Boströmb7d9a972015-12-18 16:01:11 +01003241 stats.decoder_implementation_name = "decoder_implementation_name";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003242 stats.decode_ms = 2;
3243 stats.max_decode_ms = 3;
3244 stats.current_delay_ms = 4;
3245 stats.target_delay_ms = 5;
3246 stats.jitter_buffer_ms = 6;
3247 stats.min_playout_delay_ms = 7;
3248 stats.render_delay_ms = 8;
asapersson26dd92b2016-08-30 00:45:45 -07003249 stats.width = 9;
3250 stats.height = 10;
sakale5ba44e2016-10-26 07:09:24 -07003251 stats.frames_decoded = 11;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003252 stream->SetStats(stats);
3253
3254 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003255 ASSERT_TRUE(channel_->GetStats(&info));
Peter Boströmb7d9a972015-12-18 16:01:11 +01003256 EXPECT_EQ(stats.decoder_implementation_name,
3257 info.receivers[0].decoder_implementation_name);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003258 EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
3259 EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
3260 EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
3261 EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
3262 EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
3263 EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
3264 EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
asapersson26dd92b2016-08-30 00:45:45 -07003265 EXPECT_EQ(stats.width, info.receivers[0].frame_width);
3266 EXPECT_EQ(stats.height, info.receivers[0].frame_height);
sakale5ba44e2016-10-26 07:09:24 -07003267 EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003268}
3269
Peter Boström393347f2015-04-22 14:52:45 +02003270TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesReceivePacketStatsCorrectly) {
3271 FakeVideoReceiveStream* stream = AddRecvStream();
3272 webrtc::VideoReceiveStream::Stats stats;
3273 stats.rtp_stats.transmitted.payload_bytes = 2;
3274 stats.rtp_stats.transmitted.header_bytes = 3;
3275 stats.rtp_stats.transmitted.padding_bytes = 4;
3276 stats.rtp_stats.transmitted.packets = 5;
3277 stats.rtcp_stats.cumulative_lost = 6;
3278 stats.rtcp_stats.fraction_lost = 7;
3279 stream->SetStats(stats);
3280
3281 cricket::VideoMediaInfo info;
3282 ASSERT_TRUE(channel_->GetStats(&info));
3283 EXPECT_EQ(stats.rtp_stats.transmitted.payload_bytes +
3284 stats.rtp_stats.transmitted.header_bytes +
3285 stats.rtp_stats.transmitted.padding_bytes,
3286 info.receivers[0].bytes_rcvd);
3287 EXPECT_EQ(stats.rtp_stats.transmitted.packets,
3288 info.receivers[0].packets_rcvd);
3289 EXPECT_EQ(stats.rtcp_stats.cumulative_lost, info.receivers[0].packets_lost);
3290 EXPECT_EQ(static_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8),
3291 info.receivers[0].fraction_lost);
3292}
3293
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003294TEST_F(WebRtcVideoChannel2Test, TranslatesCallStatsCorrectly) {
3295 AddSendStream();
3296 AddSendStream();
3297 webrtc::Call::Stats stats;
3298 stats.rtt_ms = 123;
3299 fake_call_->SetStats(stats);
3300
3301 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003302 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003303 ASSERT_EQ(2u, info.senders.size());
3304 EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms);
3305 EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
3306}
3307
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003308TEST_F(WebRtcVideoChannel2Test, TranslatesSenderBitrateStatsCorrectly) {
3309 FakeVideoSendStream* stream = AddSendStream();
3310 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003311 stats.target_media_bitrate_bps = 156;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003312 stats.media_bitrate_bps = 123;
3313 stats.substreams[17].total_bitrate_bps = 1;
3314 stats.substreams[17].retransmit_bitrate_bps = 2;
3315 stats.substreams[42].total_bitrate_bps = 3;
3316 stats.substreams[42].retransmit_bitrate_bps = 4;
3317 stream->SetStats(stats);
3318
3319 FakeVideoSendStream* stream2 = AddSendStream();
3320 webrtc::VideoSendStream::Stats stats2;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003321 stats2.target_media_bitrate_bps = 200;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003322 stats2.media_bitrate_bps = 321;
3323 stats2.substreams[13].total_bitrate_bps = 5;
3324 stats2.substreams[13].retransmit_bitrate_bps = 6;
3325 stats2.substreams[21].total_bitrate_bps = 7;
3326 stats2.substreams[21].retransmit_bitrate_bps = 8;
3327 stream2->SetStats(stats2);
3328
3329 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003330 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003331 ASSERT_EQ(2u, info.senders.size());
3332 // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
3333 // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
3334 EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate);
3335 EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate);
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003336 EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
3337 info.bw_estimations[0].target_enc_bitrate);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003338 EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
3339 info.bw_estimations[0].actual_enc_bitrate);
3340 EXPECT_EQ(1 + 3 + 5 + 7, info.bw_estimations[0].transmit_bitrate)
3341 << "Bandwidth stats should take all streams into account.";
3342 EXPECT_EQ(2 + 4 + 6 + 8, info.bw_estimations[0].retransmit_bitrate)
3343 << "Bandwidth stats should take all streams into account.";
3344}
3345
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003346TEST_F(WebRtcVideoChannel2Test, DefaultReceiveStreamReconfiguresToUseRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003347 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003348
Peter Boström0c4e06b2015-10-07 12:23:21 +02003349 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3350 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003351
3352 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
3353 const size_t kDataLength = 12;
3354 uint8_t data[kDataLength];
3355 memset(data, 0, sizeof(data));
3356 rtc::SetBE32(&data[8], ssrcs[0]);
jbaucheec21bd2016-03-20 06:15:43 -07003357 rtc::CopyOnWriteBuffer packet(data, kDataLength);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003358 rtc::PacketTime packet_time;
3359 channel_->OnPacketReceived(&packet, packet_time);
3360
3361 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
3362 << "No default receive stream created.";
3363 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
Peter Boströmd8b01092016-05-12 16:44:36 +02003364 EXPECT_TRUE(recv_stream->GetConfig().rtp.rtx.empty())
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003365 << "Default receive stream should not have configured RTX";
3366
3367 EXPECT_TRUE(channel_->AddRecvStream(
3368 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
3369 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
3370 << "AddRecvStream should've reconfigured, not added a new receiver.";
3371 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
Peter Boströmd8b01092016-05-12 16:44:36 +02003372 EXPECT_FALSE(recv_stream->GetConfig().rtp.rtx.empty());
3373 EXPECT_EQ(recv_stream->GetConfig().decoders.size(),
3374 recv_stream->GetConfig().rtp.rtx.size())
3375 << "RTX should be mapped for all decoders/payload types.";
3376 for (const auto& kv : recv_stream->GetConfig().rtp.rtx) {
3377 EXPECT_EQ(rtx_ssrcs[0], kv.second.ssrc);
3378 }
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003379}
3380
Peter Boströmd4362cd2015-03-25 14:17:23 +01003381TEST_F(WebRtcVideoChannel2Test, RejectsAddingStreamsWithMissingSsrcsForRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003382 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd4362cd2015-03-25 14:17:23 +01003383
Peter Boström0c4e06b2015-10-07 12:23:21 +02003384 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3385 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd4362cd2015-03-25 14:17:23 +01003386
3387 StreamParams sp =
3388 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
3389 sp.ssrcs = ssrcs; // Without RTXs, this is the important part.
3390
3391 EXPECT_FALSE(channel_->AddSendStream(sp));
3392 EXPECT_FALSE(channel_->AddRecvStream(sp));
3393}
3394
Peter Boströmd6f4c252015-03-26 16:23:04 +01003395TEST_F(WebRtcVideoChannel2Test, RejectsAddingStreamsWithOverlappingRtxSsrcs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003396 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003397
Peter Boström0c4e06b2015-10-07 12:23:21 +02003398 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3399 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd6f4c252015-03-26 16:23:04 +01003400
3401 StreamParams sp =
3402 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
3403
3404 EXPECT_TRUE(channel_->AddSendStream(sp));
3405 EXPECT_TRUE(channel_->AddRecvStream(sp));
3406
3407 // The RTX SSRC is already used in previous streams, using it should fail.
3408 sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]);
3409 EXPECT_FALSE(channel_->AddSendStream(sp));
3410 EXPECT_FALSE(channel_->AddRecvStream(sp));
3411
3412 // After removing the original stream this should be fine to add (makes sure
3413 // that RTX ssrcs are not forever taken).
3414 EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0]));
3415 EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0]));
3416 EXPECT_TRUE(channel_->AddSendStream(sp));
3417 EXPECT_TRUE(channel_->AddRecvStream(sp));
3418}
3419
3420TEST_F(WebRtcVideoChannel2Test,
3421 RejectsAddingStreamsWithOverlappingSimulcastSsrcs) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003422 static const uint32_t kFirstStreamSsrcs[] = {1, 2, 3};
3423 static const uint32_t kOverlappingStreamSsrcs[] = {4, 3, 5};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003424 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003425
Peter Boströmd6f4c252015-03-26 16:23:04 +01003426 StreamParams sp =
3427 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs));
3428
3429 EXPECT_TRUE(channel_->AddSendStream(sp));
3430 EXPECT_TRUE(channel_->AddRecvStream(sp));
3431
3432 // One of the SSRCs is already used in previous streams, using it should fail.
3433 sp = cricket::CreateSimStreamParams("cname",
3434 MAKE_VECTOR(kOverlappingStreamSsrcs));
3435 EXPECT_FALSE(channel_->AddSendStream(sp));
3436 EXPECT_FALSE(channel_->AddRecvStream(sp));
3437
3438 // After removing the original stream this should be fine to add (makes sure
3439 // that RTX ssrcs are not forever taken).
Peter Boström3548dd22015-05-22 18:48:36 +02003440 EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0]));
3441 EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0]));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003442 EXPECT_TRUE(channel_->AddSendStream(sp));
3443 EXPECT_TRUE(channel_->AddRecvStream(sp));
3444}
3445
Peter Boström259bd202015-05-28 13:39:50 +02003446TEST_F(WebRtcVideoChannel2Test, ReportsSsrcGroupsInStats) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003447 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström259bd202015-05-28 13:39:50 +02003448
3449 static const uint32_t kSenderSsrcs[] = {4, 7, 10};
3450 static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11};
3451
3452 StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams(
3453 "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs));
3454
3455 EXPECT_TRUE(channel_->AddSendStream(sender_sp));
3456
3457 static const uint32_t kReceiverSsrcs[] = {3};
3458 static const uint32_t kReceiverRtxSsrcs[] = {2};
3459
3460 StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams(
3461 "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs));
3462 EXPECT_TRUE(channel_->AddRecvStream(receiver_sp));
3463
3464 cricket::VideoMediaInfo info;
3465 ASSERT_TRUE(channel_->GetStats(&info));
3466
3467 ASSERT_EQ(1u, info.senders.size());
3468 ASSERT_EQ(1u, info.receivers.size());
3469
3470 EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups);
3471 EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups);
3472 EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
3473}
3474
pbosf42376c2015-08-28 07:35:32 -07003475TEST_F(WebRtcVideoChannel2Test, MapsReceivedPayloadTypeToCodecName) {
3476 FakeVideoReceiveStream* stream = AddRecvStream();
3477 webrtc::VideoReceiveStream::Stats stats;
3478 cricket::VideoMediaInfo info;
3479
3480 // Report no codec name before receiving.
3481 stream->SetStats(stats);
3482 ASSERT_TRUE(channel_->GetStats(&info));
3483 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
3484
3485 // Report VP8 if we're receiving it.
magjed509e4fe2016-11-18 01:34:11 -08003486 stats.current_payload_type = GetEngineCodec("VP8").id;
pbosf42376c2015-08-28 07:35:32 -07003487 stream->SetStats(stats);
3488 ASSERT_TRUE(channel_->GetStats(&info));
3489 EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());
3490
3491 // Report no codec name for unknown playload types.
3492 stats.current_payload_type = 3;
3493 stream->SetStats(stats);
3494 ASSERT_TRUE(channel_->GetStats(&info));
3495 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
3496}
3497
magjed509e4fe2016-11-18 01:34:11 -08003498void WebRtcVideoChannel2Test::TestReceiveUnsignaledSsrcPacket(
noahricd10a68e2015-07-10 11:27:55 -07003499 uint8_t payload_type,
3500 bool expect_created_receive_stream) {
magjed509e4fe2016-11-18 01:34:11 -08003501 // kRedRtxPayloadType must currently be unused.
3502 EXPECT_FALSE(FindCodecById(engine_.codecs(), kRedRtxPayloadType));
3503
noahricd10a68e2015-07-10 11:27:55 -07003504 // Add a RED RTX codec.
3505 VideoCodec red_rtx_codec =
magjed509e4fe2016-11-18 01:34:11 -08003506 VideoCodec::CreateRtxCodec(kRedRtxPayloadType, GetEngineCodec("red").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003507 recv_parameters_.codecs.push_back(red_rtx_codec);
3508 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
noahricd10a68e2015-07-10 11:27:55 -07003509
3510 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
3511 const size_t kDataLength = 12;
3512 uint8_t data[kDataLength];
3513 memset(data, 0, sizeof(data));
3514
3515 rtc::Set8(data, 1, payload_type);
3516 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
jbaucheec21bd2016-03-20 06:15:43 -07003517 rtc::CopyOnWriteBuffer packet(data, kDataLength);
noahricd10a68e2015-07-10 11:27:55 -07003518 rtc::PacketTime packet_time;
3519 channel_->OnPacketReceived(&packet, packet_time);
3520
3521 if (expect_created_receive_stream) {
3522 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
3523 << "Should have created a receive stream for payload type: "
3524 << payload_type;
3525 } else {
3526 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size())
3527 << "Shouldn't have created a receive stream for payload type: "
3528 << payload_type;
3529 }
3530}
3531
3532TEST_F(WebRtcVideoChannel2Test, Vp8PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003533 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
3534 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003535}
3536
3537TEST_F(WebRtcVideoChannel2Test, Vp9PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003538 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP9").id,
3539 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003540}
3541
3542TEST_F(WebRtcVideoChannel2Test, RtxPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003543 const cricket::VideoCodec vp8 = GetEngineCodec("VP8");
3544 const int rtx_vp8_payload_type = default_apt_rtx_types_[vp8.id];
3545 TestReceiveUnsignaledSsrcPacket(rtx_vp8_payload_type,
3546 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003547}
3548
3549TEST_F(WebRtcVideoChannel2Test, UlpfecPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003550 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("ulpfec").id,
3551 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003552}
3553
brandtr468da7c2016-11-22 02:16:47 -08003554// TODO(brandtr): Change to "non-field trial" test when FlexFEC is enabled
3555// by default.
3556TEST_F(WebRtcVideoChannel2FlexfecTest,
3557 FlexfecPacketDoesntCreateUnsignalledStream) {
3558 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("flexfec-03").id,
3559 false /* expect_created_receive_stream */);
3560}
3561
noahricd10a68e2015-07-10 11:27:55 -07003562TEST_F(WebRtcVideoChannel2Test, RedRtxPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003563 TestReceiveUnsignaledSsrcPacket(kRedRtxPayloadType,
3564 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003565}
3566
skvladdc1c62c2016-03-16 19:07:43 -07003567TEST_F(WebRtcVideoChannel2Test, CanSentMaxBitrateForExistingStream) {
3568 AddSendStream();
3569
3570 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07003571 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
skvladdc1c62c2016-03-16 19:07:43 -07003572 cricket::VideoFormat capture_format_hd =
3573 capturer.GetSupportedFormats()->front();
3574 EXPECT_EQ(1280, capture_format_hd.width);
3575 EXPECT_EQ(720, capture_format_hd.height);
3576 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
3577 EXPECT_TRUE(channel_->SetSend(true));
perkjfa10b552016-10-02 23:45:26 -07003578 capturer.CaptureFrame();
skvladdc1c62c2016-03-16 19:07:43 -07003579
perkjfa10b552016-10-02 23:45:26 -07003580 int default_encoder_bitrate = GetMaxEncoderBitrate();
brandtr468da7c2016-11-22 02:16:47 -08003581 EXPECT_GT(default_encoder_bitrate, 1000);
skvladdc1c62c2016-03-16 19:07:43 -07003582
3583 // TODO(skvlad): Resolve the inconsistency between the interpretation
3584 // of the global bitrate limit for audio and video:
3585 // - Audio: max_bandwidth_bps = 0 - fail the operation,
3586 // max_bandwidth_bps = -1 - remove the bandwidth limit
3587 // - Video: max_bandwidth_bps = 0 - remove the bandwidth limit,
3588 // max_bandwidth_bps = -1 - do not change the previously set
3589 // limit.
3590
perkjfa10b552016-10-02 23:45:26 -07003591 SetAndExpectMaxBitrate(1000, 0, 1000);
3592 SetAndExpectMaxBitrate(1000, 800, 800);
3593 SetAndExpectMaxBitrate(600, 800, 600);
3594 SetAndExpectMaxBitrate(0, 800, 800);
3595 SetAndExpectMaxBitrate(0, 0, default_encoder_bitrate);
skvladdc1c62c2016-03-16 19:07:43 -07003596
deadbeef5a4a75a2016-06-02 16:23:38 -07003597 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
skvladdc1c62c2016-03-16 19:07:43 -07003598}
3599
3600TEST_F(WebRtcVideoChannel2Test, CannotSetMaxBitrateForNonexistentStream) {
3601 webrtc::RtpParameters nonexistent_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003602 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07003603 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
3604
3605 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003606 EXPECT_FALSE(
3607 channel_->SetRtpSendParameters(last_ssrc_, nonexistent_parameters));
skvladdc1c62c2016-03-16 19:07:43 -07003608}
3609
3610TEST_F(WebRtcVideoChannel2Test,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003611 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvladdc1c62c2016-03-16 19:07:43 -07003612 // This test verifies that setting RtpParameters succeeds only if
3613 // the structure contains exactly one encoding.
deadbeefdbe2b872016-03-22 15:42:00 -07003614 // TODO(skvlad): Update this test when we start supporting setting parameters
skvladdc1c62c2016-03-16 19:07:43 -07003615 // for each encoding individually.
3616
3617 AddSendStream();
3618 // Setting RtpParameters with no encoding is expected to fail.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003619 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
3620 parameters.encodings.clear();
3621 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07003622 // Setting RtpParameters with exactly one encoding should succeed.
3623 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003624 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07003625 // Two or more encodings should result in failure.
3626 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003627 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07003628}
3629
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07003630// Test that a stream will not be sending if its encoding is made inactive
3631// through SetRtpSendParameters.
deadbeefdbe2b872016-03-22 15:42:00 -07003632// TODO(deadbeef): Update this test when we start supporting setting parameters
3633// for each encoding individually.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003634TEST_F(WebRtcVideoChannel2Test, SetRtpSendParametersEncodingsActive) {
deadbeefdbe2b872016-03-22 15:42:00 -07003635 FakeVideoSendStream* stream = AddSendStream();
3636 EXPECT_TRUE(channel_->SetSend(true));
3637 EXPECT_TRUE(stream->IsSending());
3638
3639 // Get current parameters and change "active" to false.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003640 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
deadbeefdbe2b872016-03-22 15:42:00 -07003641 ASSERT_EQ(1u, parameters.encodings.size());
3642 ASSERT_TRUE(parameters.encodings[0].active);
3643 parameters.encodings[0].active = false;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003644 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
deadbeefdbe2b872016-03-22 15:42:00 -07003645 EXPECT_FALSE(stream->IsSending());
3646
3647 // Now change it back to active and verify we resume sending.
3648 parameters.encodings[0].active = true;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003649 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
deadbeefdbe2b872016-03-22 15:42:00 -07003650 EXPECT_TRUE(stream->IsSending());
3651}
3652
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07003653// Test that if a stream is reconfigured (due to a codec change or other
3654// change) while its encoding is still inactive, it doesn't start sending.
3655TEST_F(WebRtcVideoChannel2Test,
3656 InactiveStreamDoesntStartSendingWhenReconfigured) {
3657 // Set an initial codec list, which will be modified later.
3658 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08003659 parameters1.codecs.push_back(GetEngineCodec("VP8"));
3660 parameters1.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07003661 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
3662
3663 FakeVideoSendStream* stream = AddSendStream();
3664 EXPECT_TRUE(channel_->SetSend(true));
3665 EXPECT_TRUE(stream->IsSending());
3666
3667 // Get current parameters and change "active" to false.
3668 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
3669 ASSERT_EQ(1u, parameters.encodings.size());
3670 ASSERT_TRUE(parameters.encodings[0].active);
3671 parameters.encodings[0].active = false;
3672 EXPECT_EQ(1u, GetFakeSendStreams().size());
3673 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
3674 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
3675 EXPECT_FALSE(stream->IsSending());
3676
3677 // Reorder the codec list, causing the stream to be reconfigured.
3678 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08003679 parameters2.codecs.push_back(GetEngineCodec("VP9"));
3680 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07003681 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
3682 auto new_streams = GetFakeSendStreams();
3683 // Assert that a new underlying stream was created due to the codec change.
3684 // Otherwise, this test isn't testing what it set out to test.
3685 EXPECT_EQ(1u, GetFakeSendStreams().size());
3686 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
3687
3688 // Verify that we still are not sending anything, due to the inactive
3689 // encoding.
3690 EXPECT_FALSE(new_streams[0]->IsSending());
3691}
3692
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003693// Test that GetRtpSendParameters returns the currently configured codecs.
3694TEST_F(WebRtcVideoChannel2Test, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003695 AddSendStream();
3696 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003697 parameters.codecs.push_back(GetEngineCodec("VP8"));
3698 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003699 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3700
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003701 webrtc::RtpParameters rtp_parameters =
3702 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003703 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08003704 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
3705 rtp_parameters.codecs[0]);
3706 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
3707 rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003708}
3709
3710// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003711TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003712 AddSendStream();
3713 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003714 parameters.codecs.push_back(GetEngineCodec("VP8"));
3715 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003716 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3717
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003718 webrtc::RtpParameters initial_params =
3719 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003720
3721 // We should be able to set the params we just got.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003722 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003723
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003724 // ... And this shouldn't change the params returned by GetRtpSendParameters.
3725 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(last_ssrc_));
3726}
3727
3728// Test that GetRtpReceiveParameters returns the currently configured codecs.
3729TEST_F(WebRtcVideoChannel2Test, GetRtpReceiveParametersCodecs) {
3730 AddRecvStream();
3731 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003732 parameters.codecs.push_back(GetEngineCodec("VP8"));
3733 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003734 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
3735
3736 webrtc::RtpParameters rtp_parameters =
3737 channel_->GetRtpReceiveParameters(last_ssrc_);
3738 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08003739 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
3740 rtp_parameters.codecs[0]);
3741 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
3742 rtp_parameters.codecs[1]);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003743}
3744
johan073ece42016-08-26 02:59:47 -07003745#if defined(WEBRTC_USE_H264)
johan3859c892016-08-05 09:19:25 -07003746TEST_F(WebRtcVideoChannel2Test, GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07003747#else
3748TEST_F(WebRtcVideoChannel2Test, DISABLED_GetRtpReceiveFmtpSprop) {
3749#endif
johan3859c892016-08-05 09:19:25 -07003750 cricket::VideoRecvParameters parameters;
perkj26752742016-10-24 01:21:16 -07003751 cricket::VideoCodec kH264sprop1(101, "H264");
johan3859c892016-08-05 09:19:25 -07003752 kH264sprop1.SetParam("sprop-parameter-sets", "uvw");
3753 parameters.codecs.push_back(kH264sprop1);
perkj26752742016-10-24 01:21:16 -07003754 cricket::VideoCodec kH264sprop2(102, "H264");
johan3859c892016-08-05 09:19:25 -07003755 kH264sprop2.SetParam("sprop-parameter-sets", "xyz");
3756 parameters.codecs.push_back(kH264sprop2);
3757 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
3758
3759 FakeVideoReceiveStream* recv_stream = AddRecvStream();
3760 const webrtc::VideoReceiveStream::Config& cfg = recv_stream->GetConfig();
3761 webrtc::RtpParameters rtp_parameters =
3762 channel_->GetRtpReceiveParameters(last_ssrc_);
3763 ASSERT_EQ(2u, rtp_parameters.codecs.size());
3764 EXPECT_EQ(kH264sprop1.ToCodecParameters(), rtp_parameters.codecs[0]);
3765 ASSERT_EQ(2u, cfg.decoders.size());
3766 EXPECT_EQ(101, cfg.decoders[0].payload_type);
3767 EXPECT_EQ("H264", cfg.decoders[0].payload_name);
3768 std::string sprop;
3769 const webrtc::DecoderSpecificSettings* decoder_specific;
3770 decoder_specific = &cfg.decoders[0].decoder_specific;
3771 ASSERT_TRUE(static_cast<bool>(decoder_specific->h264_extra_settings));
3772 sprop = decoder_specific->h264_extra_settings->sprop_parameter_sets;
3773 EXPECT_EQ("uvw", sprop);
3774
3775 EXPECT_EQ(102, cfg.decoders[1].payload_type);
3776 EXPECT_EQ("H264", cfg.decoders[1].payload_name);
3777 decoder_specific = &cfg.decoders[1].decoder_specific;
3778 ASSERT_TRUE(static_cast<bool>(decoder_specific->h264_extra_settings));
3779 sprop = decoder_specific->h264_extra_settings->sprop_parameter_sets;
3780 EXPECT_EQ("xyz", sprop);
3781}
3782
sakal1fd95952016-06-22 00:46:15 -07003783// Test that RtpParameters for receive stream has one encoding and it has
3784// the correct SSRC.
3785TEST_F(WebRtcVideoChannel2Test, RtpEncodingParametersSsrcIsSet) {
3786 AddRecvStream();
3787
3788 webrtc::RtpParameters rtp_parameters =
3789 channel_->GetRtpReceiveParameters(last_ssrc_);
3790 ASSERT_EQ(1u, rtp_parameters.encodings.size());
3791 EXPECT_EQ(rtc::Optional<uint32_t>(last_ssrc_),
3792 rtp_parameters.encodings[0].ssrc);
3793}
3794
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003795// Test that if we set/get parameters multiple times, we get the same results.
3796TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpReceiveParameters) {
3797 AddRecvStream();
3798 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003799 parameters.codecs.push_back(GetEngineCodec("VP8"));
3800 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003801 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
3802
3803 webrtc::RtpParameters initial_params =
3804 channel_->GetRtpReceiveParameters(last_ssrc_);
3805
3806 // We should be able to set the params we just got.
3807 EXPECT_TRUE(channel_->SetRtpReceiveParameters(last_ssrc_, initial_params));
3808
3809 // ... And this shouldn't change the params returned by
3810 // GetRtpReceiveParameters.
3811 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(last_ssrc_));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003812}
3813
Peter Boström3548dd22015-05-22 18:48:36 +02003814void WebRtcVideoChannel2Test::TestReceiverLocalSsrcConfiguration(
3815 bool receiver_first) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003816 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström3548dd22015-05-22 18:48:36 +02003817
3818 const uint32_t kSenderSsrc = 0xC0FFEE;
Peter Boströmdfa28152015-10-21 17:21:10 +02003819 const uint32_t kSecondSenderSsrc = 0xBADCAFE;
Peter Boström3548dd22015-05-22 18:48:36 +02003820 const uint32_t kReceiverSsrc = 0x4711;
Peter Boströmdfa28152015-10-21 17:21:10 +02003821 const uint32_t kExpectedDefaultReceiverSsrc = 1;
Peter Boström3548dd22015-05-22 18:48:36 +02003822
3823 if (receiver_first) {
3824 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
3825 std::vector<FakeVideoReceiveStream*> receive_streams =
3826 fake_call_->GetVideoReceiveStreams();
3827 ASSERT_EQ(1u, receive_streams.size());
Peter Boströmdfa28152015-10-21 17:21:10 +02003828 // Default local SSRC when we have no sender.
3829 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
3830 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02003831 }
3832 AddSendStream(StreamParams::CreateLegacy(kSenderSsrc));
3833 if (!receiver_first)
3834 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
3835 std::vector<FakeVideoReceiveStream*> receive_streams =
3836 fake_call_->GetVideoReceiveStreams();
3837 ASSERT_EQ(1u, receive_streams.size());
3838 EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boströmdfa28152015-10-21 17:21:10 +02003839
3840 // Removing first sender should fall back to another (in this case the second)
3841 // local send stream's SSRC.
3842 AddSendStream(StreamParams::CreateLegacy(kSecondSenderSsrc));
3843 ASSERT_TRUE(channel_->RemoveSendStream(kSenderSsrc));
3844 receive_streams =
3845 fake_call_->GetVideoReceiveStreams();
3846 ASSERT_EQ(1u, receive_streams.size());
3847 EXPECT_EQ(kSecondSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
3848
3849 // Removing the last sender should fall back to default local SSRC.
3850 ASSERT_TRUE(channel_->RemoveSendStream(kSecondSenderSsrc));
3851 receive_streams =
3852 fake_call_->GetVideoReceiveStreams();
3853 ASSERT_EQ(1u, receive_streams.size());
3854 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
3855 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02003856}
3857
3858TEST_F(WebRtcVideoChannel2Test, ConfiguresLocalSsrc) {
3859 TestReceiverLocalSsrcConfiguration(false);
3860}
3861
3862TEST_F(WebRtcVideoChannel2Test, ConfiguresLocalSsrcOnExistingReceivers) {
3863 TestReceiverLocalSsrcConfiguration(true);
3864}
3865
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003866class WebRtcVideoChannel2SimulcastTest : public testing::Test {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003867 public:
skvlad11a9cbf2016-10-07 11:53:05 -07003868 WebRtcVideoChannel2SimulcastTest()
3869 : fake_call_(webrtc::Call::Config(&event_log_)) {}
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003870
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003871 void SetUp() override {
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +02003872 engine_.Init();
nisse51542be2016-02-12 02:27:06 -08003873 channel_.reset(
3874 engine_.CreateChannel(&fake_call_, MediaConfig(), VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08003875 channel_->OnReadyToSend(true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003876 last_ssrc_ = 123;
3877 }
3878
3879 protected:
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003880 void VerifySimulcastSettings(const VideoCodec& codec,
perkj26752742016-10-24 01:21:16 -07003881 int capture_width,
3882 int capture_height,
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003883 size_t num_configured_streams,
pbosbe16f792015-10-16 12:49:39 -07003884 size_t expected_num_streams) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003885 cricket::VideoSendParameters parameters;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003886 parameters.codecs.push_back(codec);
3887 ASSERT_TRUE(channel_->SetSendParameters(parameters));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003888
Peter Boström0c4e06b2015-10-07 12:23:21 +02003889 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
henrikg91d6ede2015-09-17 00:24:34 -07003890 RTC_DCHECK(num_configured_streams <= ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003891 ssrcs.resize(num_configured_streams);
3892
3893 FakeVideoSendStream* stream =
3894 AddSendStream(CreateSimStreamParams("cname", ssrcs));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003895 // Send a full-size frame to trigger a stream reconfiguration to use all
3896 // expected simulcast layers.
3897 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07003898 EXPECT_TRUE(
3899 channel_->SetVideoSend(ssrcs.front(), true, nullptr, &capturer));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003900 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(cricket::VideoFormat(
perkj26752742016-10-24 01:21:16 -07003901 capture_width, capture_height,
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003902 cricket::VideoFormat::FpsToInterval(30),
3903 cricket::FOURCC_I420)));
3904 channel_->SetSend(true);
3905 EXPECT_TRUE(capturer.CaptureFrame());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003906
3907 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
3908 ASSERT_EQ(expected_num_streams, video_streams.size());
3909
3910 std::vector<webrtc::VideoStream> expected_streams = GetSimulcastConfig(
perkj26752742016-10-24 01:21:16 -07003911 num_configured_streams, capture_width, capture_height, 0, kDefaultQpMax,
3912 kDefaultVideoMaxFramerate);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003913
3914 ASSERT_EQ(expected_streams.size(), video_streams.size());
3915
3916 size_t num_streams = video_streams.size();
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003917 int total_max_bitrate_bps = 0;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003918 for (size_t i = 0; i < num_streams; ++i) {
3919 EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
3920 EXPECT_EQ(expected_streams[i].height, video_streams[i].height);
3921
3922 EXPECT_GT(video_streams[i].max_framerate, 0);
3923 EXPECT_EQ(expected_streams[i].max_framerate,
3924 video_streams[i].max_framerate);
3925
3926 EXPECT_GT(video_streams[i].min_bitrate_bps, 0);
3927 EXPECT_EQ(expected_streams[i].min_bitrate_bps,
3928 video_streams[i].min_bitrate_bps);
3929
3930 EXPECT_GT(video_streams[i].target_bitrate_bps, 0);
3931 EXPECT_EQ(expected_streams[i].target_bitrate_bps,
3932 video_streams[i].target_bitrate_bps);
3933
3934 EXPECT_GT(video_streams[i].max_bitrate_bps, 0);
3935 EXPECT_EQ(expected_streams[i].max_bitrate_bps,
3936 video_streams[i].max_bitrate_bps);
3937
3938 EXPECT_GT(video_streams[i].max_qp, 0);
3939 EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp);
3940
3941 EXPECT_FALSE(expected_streams[i].temporal_layer_thresholds_bps.empty());
3942 EXPECT_EQ(expected_streams[i].temporal_layer_thresholds_bps,
3943 video_streams[i].temporal_layer_thresholds_bps);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003944
3945 if (i == num_streams - 1) {
3946 total_max_bitrate_bps += video_streams[i].max_bitrate_bps;
3947 } else {
3948 total_max_bitrate_bps += video_streams[i].target_bitrate_bps;
3949 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003950 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003951
deadbeef5a4a75a2016-06-02 16:23:38 -07003952 EXPECT_TRUE(channel_->SetVideoSend(ssrcs.front(), true, nullptr, nullptr));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003953 }
3954
3955 FakeVideoSendStream* AddSendStream() {
3956 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++));
3957 }
3958
3959 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
3960 size_t num_streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003961 fake_call_.GetVideoSendStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003962 EXPECT_TRUE(channel_->AddSendStream(sp));
3963 std::vector<FakeVideoSendStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003964 fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003965 EXPECT_EQ(num_streams + 1, streams.size());
3966 return streams[streams.size() - 1];
3967 }
3968
3969 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003970 return fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003971 }
3972
3973 FakeVideoReceiveStream* AddRecvStream() {
3974 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++));
3975 }
3976
3977 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
3978 size_t num_streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003979 fake_call_.GetVideoReceiveStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003980 EXPECT_TRUE(channel_->AddRecvStream(sp));
3981 std::vector<FakeVideoReceiveStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003982 fake_call_.GetVideoReceiveStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003983 EXPECT_EQ(num_streams + 1, streams.size());
3984 return streams[streams.size() - 1];
3985 }
3986
skvlad11a9cbf2016-10-07 11:53:05 -07003987 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003988 FakeCall fake_call_;
3989 WebRtcVideoEngine2 engine_;
kwiberg686a8ef2016-02-26 03:00:35 -08003990 std::unique_ptr<VideoMediaChannel> channel_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02003991 uint32_t last_ssrc_;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003992};
3993
3994TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith2SimulcastStreams) {
magjed509e4fe2016-11-18 01:34:11 -08003995 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 640, 360, 2, 2);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003996}
3997
3998TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith3SimulcastStreams) {
magjed509e4fe2016-11-18 01:34:11 -08003999 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004000}
4001
4002// Test that we normalize send codec format size in simulcast.
4003TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
magjed509e4fe2016-11-18 01:34:11 -08004004 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 541, 271, 2, 2);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004005}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004006} // namespace cricket