blob: c473a4099f98d9838a0a9de28857997253f87141 [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));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000356
357 EXPECT_TRUE(
358 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Per21d45d22016-10-30 21:37:57 +0100359 EXPECT_EQ(0, encoder_factory.GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000360 EXPECT_TRUE(channel->SetSend(true));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000361 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700362 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000363 EXPECT_EQ(cricket::CS_RUNNING,
364 capturer.Start(capturer.GetSupportedFormats()->front()));
365 EXPECT_TRUE(capturer.CaptureFrame());
Per21d45d22016-10-30 21:37:57 +0100366 // Sending one frame will have allocate the encoder.
367 ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(1));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000368 EXPECT_TRUE_WAIT(encoder_factory.encoders()[0]->GetNumEncodedFrames() > 0,
369 kTimeout);
370
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000371 int num_created_encoders = encoder_factory.GetNumCreatedEncoders();
Per21d45d22016-10-30 21:37:57 +0100372 EXPECT_EQ(num_created_encoders, 1);
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000373
374 // Setting codecs of the same type should not reallocate any encoders
375 // (expecting a no-op).
magjed509e4fe2016-11-18 01:34:11 -0800376 cricket::VideoSendParameters parameters;
377 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200378 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000379 EXPECT_EQ(num_created_encoders, encoder_factory.GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000380
381 // Remove stream previously added to free the external encoder instance.
382 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
383 EXPECT_EQ(0u, encoder_factory.encoders().size());
384}
385
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700386// Test that when an external encoder factory supports a codec we don't
387// internally support, we still add an RTX codec for it.
388// TODO(deadbeef): Currently this test is only effective if WebRTC is
389// built with no internal H264 support. This test should be updated
390// if/when we start adding RTX codecs for unrecognized codec names.
391TEST_F(WebRtcVideoEngine2Test, RtxCodecAddedForExternalCodec) {
magjed725e4842016-11-16 00:48:13 -0800392 using webrtc::H264::ProfileLevelIdToString;
393 using webrtc::H264::ProfileLevelId;
394 using webrtc::H264::kLevel1;
395 cricket::VideoCodec h264_constrained_baseline("H264");
396 h264_constrained_baseline.params[kH264FmtpProfileLevelId] =
397 *ProfileLevelIdToString(
398 ProfileLevelId(webrtc::H264::kProfileConstrainedBaseline, kLevel1));
399 cricket::VideoCodec h264_constrained_high("H264");
400 h264_constrained_high.params[kH264FmtpProfileLevelId] =
401 *ProfileLevelIdToString(
402 ProfileLevelId(webrtc::H264::kProfileConstrainedHigh, kLevel1));
403 cricket::VideoCodec h264_high("H264");
404 h264_high.params[kH264FmtpProfileLevelId] = *ProfileLevelIdToString(
405 ProfileLevelId(webrtc::H264::kProfileHigh, kLevel1));
406
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700407 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed725e4842016-11-16 00:48:13 -0800408 encoder_factory.AddSupportedVideoCodec(h264_constrained_baseline);
409 encoder_factory.AddSupportedVideoCodec(h264_constrained_high);
410 encoder_factory.AddSupportedVideoCodec(h264_high);
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700411 engine_.SetExternalEncoderFactory(&encoder_factory);
412 engine_.Init();
413
magjed725e4842016-11-16 00:48:13 -0800414 // First figure out what payload types the test codecs got assigned.
415 const std::vector<cricket::VideoCodec> codecs = engine_.codecs();
magjed509e4fe2016-11-18 01:34:11 -0800416 // Now search for RTX codecs for them. Expect that they all have associated
417 // RTX codecs.
magjed725e4842016-11-16 00:48:13 -0800418 EXPECT_TRUE(HasRtxCodec(
419 codecs, FindMatchingCodec(codecs, h264_constrained_baseline)->id));
420 EXPECT_TRUE(HasRtxCodec(
421 codecs, FindMatchingCodec(codecs, h264_constrained_high)->id));
magjed509e4fe2016-11-18 01:34:11 -0800422 EXPECT_TRUE(HasRtxCodec(
magjed725e4842016-11-16 00:48:13 -0800423 codecs, FindMatchingCodec(codecs, h264_high)->id));
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700424}
425
Peter Boströme4499152016-02-05 11:13:28 +0100426void WebRtcVideoEngine2Test::TestExtendedEncoderOveruse(
427 bool use_external_encoder) {
428 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700429 encoder_factory.AddSupportedVideoCodecType("VP8");
kwiberg686a8ef2016-02-26 03:00:35 -0800430 std::unique_ptr<VideoMediaChannel> channel;
skvlad11a9cbf2016-10-07 11:53:05 -0700431 FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_));
Peter Boströme4499152016-02-05 11:13:28 +0100432 call_.reset(fake_call);
433 if (use_external_encoder) {
magjed509e4fe2016-11-18 01:34:11 -0800434 channel.reset(SetUpForExternalEncoderFactory(&encoder_factory));
Peter Boströme4499152016-02-05 11:13:28 +0100435 } else {
436 engine_.Init();
nisse51542be2016-02-12 02:27:06 -0800437 channel.reset(
438 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions()));
Peter Boströme4499152016-02-05 11:13:28 +0100439 }
440 ASSERT_TRUE(
441 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
magjed509e4fe2016-11-18 01:34:11 -0800442 cricket::VideoSendParameters parameters;
443 parameters.codecs.push_back(GetEngineCodec("VP8"));
Peter Boströme4499152016-02-05 11:13:28 +0100444 EXPECT_TRUE(channel->SetSendParameters(parameters));
445 EXPECT_TRUE(channel->SetSend(true));
446 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
447
448 EXPECT_EQ(use_external_encoder,
449 stream->GetConfig().encoder_settings.full_overuse_time);
450 // Remove stream previously added to free the external encoder instance.
451 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
452}
453
454TEST_F(WebRtcVideoEngine2Test, EnablesFullEncoderTimeForExternalEncoders) {
455 TestExtendedEncoderOveruse(true);
456}
457
458TEST_F(WebRtcVideoEngine2Test, DisablesFullEncoderTimeForNonExternalEncoders) {
459 TestExtendedEncoderOveruse(false);
460}
461
Peter Boström12996152016-05-14 02:03:18 +0200462#if !defined(RTC_DISABLE_VP9)
Peter Boström53eda3d2015-03-27 15:53:18 +0100463TEST_F(WebRtcVideoEngine2Test, CanConstructDecoderForVp9EncoderFactory) {
464 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700465 encoder_factory.AddSupportedVideoCodecType("VP9");
Peter Boström53eda3d2015-03-27 15:53:18 +0100466
kwiberg686a8ef2016-02-26 03:00:35 -0800467 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800468 SetUpForExternalEncoderFactory(&encoder_factory));
Peter Boström53eda3d2015-03-27 15:53:18 +0100469
470 EXPECT_TRUE(
471 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
472}
Peter Boström12996152016-05-14 02:03:18 +0200473#endif // !defined(RTC_DISABLE_VP9)
Peter Boström53eda3d2015-03-27 15:53:18 +0100474
qiangchenc27d89f2015-07-16 10:27:16 -0700475TEST_F(WebRtcVideoEngine2Test, PropagatesInputFrameTimestamp) {
476 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700477 encoder_factory.AddSupportedVideoCodecType("VP8");
skvlad11a9cbf2016-10-07 11:53:05 -0700478 FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200479 call_.reset(fake_call);
kwiberg686a8ef2016-02-26 03:00:35 -0800480 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800481 SetUpForExternalEncoderFactory(&encoder_factory));
qiangchenc27d89f2015-07-16 10:27:16 -0700482
483 EXPECT_TRUE(
484 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
485
486 FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700487 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
qiangchenc27d89f2015-07-16 10:27:16 -0700488 capturer.Start(cricket::VideoFormat(1280, 720,
489 cricket::VideoFormat::FpsToInterval(60),
490 cricket::FOURCC_I420));
491 channel->SetSend(true);
492
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200493 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
qiangchenc27d89f2015-07-16 10:27:16 -0700494
495 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700496 int64_t last_timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700497 for (int i = 0; i < 10; i++) {
498 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700499 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700500 int64_t interval = timestamp - last_timestamp;
501
502 // Precision changes from nanosecond to millisecond.
503 // Allow error to be no more than 1.
504 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1);
505
506 last_timestamp = timestamp;
507 }
508
509 capturer.Start(cricket::VideoFormat(1280, 720,
510 cricket::VideoFormat::FpsToInterval(30),
511 cricket::FOURCC_I420));
512
513 EXPECT_TRUE(capturer.CaptureFrame());
514 last_timestamp = stream->GetLastTimestamp();
515 for (int i = 0; i < 10; i++) {
516 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700517 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700518 int64_t interval = timestamp - last_timestamp;
519
520 // Precision changes from nanosecond to millisecond.
521 // Allow error to be no more than 1.
522 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1);
523
524 last_timestamp = timestamp;
525 }
526
527 // Remove stream previously added to free the external encoder instance.
528 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
529}
530
magjed509e4fe2016-11-18 01:34:11 -0800531cricket::VideoCodec WebRtcVideoEngine2Test::GetEngineCodec(
532 const std::string& name) {
533 for (const cricket::VideoCodec& engine_codec : engine_.codecs()) {
534 if (CodecNamesEq(name, engine_codec.name))
535 return engine_codec;
536 }
537 // This point should never be reached.
538 ADD_FAILURE() << "Unrecognized codec name: " << name;
539 return cricket::VideoCodec();
540}
541
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000542VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalEncoderFactory(
magjed509e4fe2016-11-18 01:34:11 -0800543 cricket::WebRtcVideoEncoderFactory* encoder_factory) {
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000544 engine_.SetExternalEncoderFactory(encoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200545 engine_.Init();
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000546
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000547 VideoMediaChannel* channel =
nisse51542be2016-02-12 02:27:06 -0800548 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200549 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800550 // We need to look up the codec in the engine to get the correct payload type.
551 for (const VideoCodec& codec : encoder_factory->supported_codecs())
552 parameters.codecs.push_back(GetEngineCodec(codec.name));
553
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200554 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000555
556 return channel;
557}
558
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000559VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalDecoderFactory(
560 cricket::WebRtcVideoDecoderFactory* decoder_factory,
561 const std::vector<VideoCodec>& codecs) {
562 engine_.SetExternalDecoderFactory(decoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200563 engine_.Init();
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000564
565 VideoMediaChannel* channel =
nisse51542be2016-02-12 02:27:06 -0800566 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200567 cricket::VideoRecvParameters parameters;
568 parameters.codecs = codecs;
569 EXPECT_TRUE(channel->SetRecvParameters(parameters));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000570
571 return channel;
572}
573
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000574TEST_F(WebRtcVideoEngine2Test, UsesSimulcastAdapterForVp8Factories) {
575 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700576 encoder_factory.AddSupportedVideoCodecType("VP8");
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000577
kwiberg686a8ef2016-02-26 03:00:35 -0800578 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800579 SetUpForExternalEncoderFactory(&encoder_factory));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000580
Peter Boström0c4e06b2015-10-07 12:23:21 +0200581 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000582
583 EXPECT_TRUE(
584 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
585 EXPECT_TRUE(channel->SetSend(true));
586
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000587 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700588 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, &capturer));
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000589 EXPECT_EQ(cricket::CS_RUNNING,
590 capturer.Start(capturer.GetSupportedFormats()->front()));
591 EXPECT_TRUE(capturer.CaptureFrame());
592
pbos14fe7082016-04-20 06:35:56 -0700593 ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(2));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000594
595 // Verify that encoders are configured for simulcast through adapter
596 // (increasing resolution and only configured to send one stream each).
597 int prev_width = -1;
598 for (size_t i = 0; i < encoder_factory.encoders().size(); ++i) {
pbos14fe7082016-04-20 06:35:56 -0700599 ASSERT_TRUE(encoder_factory.encoders()[i]->WaitForInitEncode());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000600 webrtc::VideoCodec codec_settings =
601 encoder_factory.encoders()[i]->GetCodecSettings();
602 EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
603 EXPECT_GT(codec_settings.width, prev_width);
604 prev_width = codec_settings.width;
605 }
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000606
deadbeef5a4a75a2016-06-02 16:23:38 -0700607 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, nullptr));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000608
609 channel.reset();
610 ASSERT_EQ(0u, encoder_factory.encoders().size());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000611}
612
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000613TEST_F(WebRtcVideoEngine2Test, ChannelWithExternalH264CanChangeToInternalVp8) {
614 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700615 encoder_factory.AddSupportedVideoCodecType("H264");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000616
kwiberg686a8ef2016-02-26 03:00:35 -0800617 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800618 SetUpForExternalEncoderFactory(&encoder_factory));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000619
620 EXPECT_TRUE(
621 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
622 ASSERT_EQ(1u, encoder_factory.encoders().size());
623
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200624 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800625 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200626 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000627 ASSERT_EQ(0u, encoder_factory.encoders().size());
628}
629
630TEST_F(WebRtcVideoEngine2Test,
631 DontUseExternalEncoderFactoryForUnsupportedCodecs) {
632 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700633 encoder_factory.AddSupportedVideoCodecType("H264");
magjed509e4fe2016-11-18 01:34:11 -0800634
635 engine_.SetExternalEncoderFactory(&encoder_factory);
636 engine_.Init();
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000637
kwiberg686a8ef2016-02-26 03:00:35 -0800638 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800639 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions()));
640 cricket::VideoSendParameters parameters;
641 parameters.codecs.push_back(GetEngineCodec("VP8"));
642 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000643
644 EXPECT_TRUE(
645 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000646 // Make sure DestroyVideoEncoder was called on the factory.
647 ASSERT_EQ(0u, encoder_factory.encoders().size());
648}
649
650TEST_F(WebRtcVideoEngine2Test,
651 UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
652 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700653 encoder_factory.AddSupportedVideoCodecType("VP8");
654 encoder_factory.AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000655
magjed509e4fe2016-11-18 01:34:11 -0800656 engine_.SetExternalEncoderFactory(&encoder_factory);
657 engine_.Init();
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000658
kwiberg686a8ef2016-02-26 03:00:35 -0800659 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800660 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions()));
661 cricket::VideoSendParameters parameters;
662 parameters.codecs.push_back(GetEngineCodec("VP8"));
663 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000664
Peter Boström0c4e06b2015-10-07 12:23:21 +0200665 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000666
667 EXPECT_TRUE(
668 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
669 EXPECT_TRUE(channel->SetSend(true));
670
671 // Send a fake frame, or else the media engine will configure the simulcast
672 // encoder adapter at a low-enough size that it'll only create a single
673 // encoder layer.
674 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700675 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, &capturer));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000676 EXPECT_EQ(cricket::CS_RUNNING,
677 capturer.Start(capturer.GetSupportedFormats()->front()));
678 EXPECT_TRUE(capturer.CaptureFrame());
679
pbos14fe7082016-04-20 06:35:56 -0700680 ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(2));
681 ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000682 EXPECT_EQ(webrtc::kVideoCodecVP8,
683 encoder_factory.encoders()[0]->GetCodecSettings().codecType);
684
685 channel.reset();
686 // Make sure DestroyVideoEncoder was called on the factory.
687 EXPECT_EQ(0u, encoder_factory.encoders().size());
688}
689
690TEST_F(WebRtcVideoEngine2Test,
691 DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
692 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700693 encoder_factory.AddSupportedVideoCodecType("VP8");
694 encoder_factory.AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000695
magjed509e4fe2016-11-18 01:34:11 -0800696 engine_.SetExternalEncoderFactory(&encoder_factory);
697 engine_.Init();
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000698
kwiberg686a8ef2016-02-26 03:00:35 -0800699 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800700 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions()));
701 cricket::VideoSendParameters parameters;
702 parameters.codecs.push_back(GetEngineCodec("H264"));
703 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000704
705 EXPECT_TRUE(
706 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
707 ASSERT_EQ(1u, encoder_factory.encoders().size());
Per21d45d22016-10-30 21:37:57 +0100708
709 // Send a frame of 720p. This should trigger a "real" encoder initialization.
710 cricket::VideoFormat format(
711 1280, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
712 cricket::FakeVideoCapturer capturer;
713 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
714 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format));
715 EXPECT_TRUE(capturer.CaptureFrame());
pbos14fe7082016-04-20 06:35:56 -0700716 ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000717 EXPECT_EQ(webrtc::kVideoCodecH264,
718 encoder_factory.encoders()[0]->GetCodecSettings().codecType);
719
720 channel.reset();
721 // Make sure DestroyVideoEncoder was called on the factory.
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000722 ASSERT_EQ(0u, encoder_factory.encoders().size());
723}
724
noahricfdac5162015-08-27 01:59:29 -0700725TEST_F(WebRtcVideoEngine2Test, SimulcastDisabledForH264) {
726 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700727 encoder_factory.AddSupportedVideoCodecType("H264");
noahricfdac5162015-08-27 01:59:29 -0700728
kwiberg686a8ef2016-02-26 03:00:35 -0800729 std::unique_ptr<VideoMediaChannel> channel(
magjed509e4fe2016-11-18 01:34:11 -0800730 SetUpForExternalEncoderFactory(&encoder_factory));
noahricfdac5162015-08-27 01:59:29 -0700731
Peter Boström0c4e06b2015-10-07 12:23:21 +0200732 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
noahricfdac5162015-08-27 01:59:29 -0700733 EXPECT_TRUE(
734 channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs)));
Peter Boströmce23bee2016-02-02 14:14:30 +0100735
736 // Send a frame of 720p. This should trigger a "real" encoder initialization.
noahricfdac5162015-08-27 01:59:29 -0700737 cricket::VideoFormat format(
738 1280, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
Peter Boströmce23bee2016-02-02 14:14:30 +0100739 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700740 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], true, nullptr, &capturer));
Peter Boströmce23bee2016-02-02 14:14:30 +0100741 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format));
742 EXPECT_TRUE(capturer.CaptureFrame());
743
noahricfdac5162015-08-27 01:59:29 -0700744 ASSERT_EQ(1u, encoder_factory.encoders().size());
745 FakeWebRtcVideoEncoder* encoder = encoder_factory.encoders()[0];
pbos14fe7082016-04-20 06:35:56 -0700746 ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode());
noahricfdac5162015-08-27 01:59:29 -0700747 EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
748 EXPECT_EQ(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
deadbeef5a4a75a2016-06-02 16:23:38 -0700749 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], true, nullptr, nullptr));
noahricfdac5162015-08-27 01:59:29 -0700750}
751
hbosbab934b2016-01-27 01:36:03 -0800752// Test that external codecs are added to the end of the supported codec list.
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000753TEST_F(WebRtcVideoEngine2Test, ReportSupportedExternalCodecs) {
754 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700755 encoder_factory.AddSupportedVideoCodecType("FakeExternalCodec");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000756 engine_.SetExternalEncoderFactory(&encoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200757 engine_.Init();
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000758
759 std::vector<cricket::VideoCodec> codecs(engine_.codecs());
760 ASSERT_GE(codecs.size(), 2u);
761 cricket::VideoCodec internal_codec = codecs.front();
762 cricket::VideoCodec external_codec = codecs.back();
763
764 // The external codec will appear at last.
765 EXPECT_EQ("VP8", internal_codec.name);
hbosbab934b2016-01-27 01:36:03 -0800766 EXPECT_EQ("FakeExternalCodec", external_codec.name);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000767}
768
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000769TEST_F(WebRtcVideoEngine2Test, RegisterExternalDecodersIfSupported) {
770 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
771 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200772 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800773 parameters.codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000774
kwiberg686a8ef2016-02-26 03:00:35 -0800775 std::unique_ptr<VideoMediaChannel> channel(
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200776 SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000777
778 EXPECT_TRUE(
779 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
780 ASSERT_EQ(1u, decoder_factory.decoders().size());
781
782 // Setting codecs of the same type should not reallocate the decoder.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200783 EXPECT_TRUE(channel->SetRecvParameters(parameters));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000784 EXPECT_EQ(1, decoder_factory.GetNumCreatedDecoders());
785
786 // Remove stream previously added to free the external decoder instance.
787 EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
788 EXPECT_EQ(0u, decoder_factory.decoders().size());
789}
790
791// Verifies that we can set up decoders that are not internally supported.
792TEST_F(WebRtcVideoEngine2Test, RegisterExternalH264DecoderIfSupported) {
793 // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We
794 // can't even query the WebRtcVideoDecoderFactory for supported codecs.
795 // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
796 // codecs.
797 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
magjed1e45cc62016-10-28 07:43:45 -0700798 encoder_factory.AddSupportedVideoCodecType("H264");
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000799 engine_.SetExternalEncoderFactory(&encoder_factory);
800 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
801 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264);
802 std::vector<cricket::VideoCodec> codecs;
magjed509e4fe2016-11-18 01:34:11 -0800803 codecs.push_back(GetEngineCodec("H264"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000804
kwiberg686a8ef2016-02-26 03:00:35 -0800805 std::unique_ptr<VideoMediaChannel> channel(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000806 SetUpForExternalDecoderFactory(&decoder_factory, codecs));
807
808 EXPECT_TRUE(
809 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
810 ASSERT_EQ(1u, decoder_factory.decoders().size());
811}
812
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000813class WebRtcVideoChannel2BaseTest
814 : public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> {
815 protected:
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000816 typedef VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> Base;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000817
magjed509e4fe2016-11-18 01:34:11 -0800818 cricket::VideoCodec GetEngineCodec(const std::string& name) {
819 for (const cricket::VideoCodec& engine_codec : engine_.codecs()) {
820 if (CodecNamesEq(name, engine_codec.name))
821 return engine_codec;
822 }
823 // This point should never be reached.
824 ADD_FAILURE() << "Unrecognized codec name: " << name;
825 return cricket::VideoCodec();
826 }
827
828 cricket::VideoCodec DefaultCodec() override { return GetEngineCodec("VP8"); }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000829};
830
sakal1fd95952016-06-22 00:46:15 -0700831// Verifies that id given in stream params is passed to the decoder factory.
832TEST_F(WebRtcVideoEngine2Test, StreamParamsIdPassedToDecoderFactory) {
833 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
834 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
835 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800836 parameters.codecs.push_back(GetEngineCodec("VP8"));
sakal1fd95952016-06-22 00:46:15 -0700837
838 std::unique_ptr<VideoMediaChannel> channel(
839 SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs));
840
841 StreamParams sp = cricket::StreamParams::CreateLegacy(kSsrc);
842 sp.id = "FakeStreamParamsId";
843 EXPECT_TRUE(channel->AddRecvStream(sp));
844 EXPECT_EQ(1u, decoder_factory.decoders().size());
845
846 std::vector<cricket::VideoDecoderParams> params = decoder_factory.params();
847 ASSERT_EQ(1u, params.size());
848 EXPECT_EQ(sp.id, params[0].receive_stream_id);
849}
850
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000851#define WEBRTC_BASE_TEST(test) \
852 TEST_F(WebRtcVideoChannel2BaseTest, test) { Base::test(); }
853
854#define WEBRTC_DISABLED_BASE_TEST(test) \
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000855 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_##test) { Base::test(); }
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000856
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000857WEBRTC_BASE_TEST(SetSend);
858WEBRTC_BASE_TEST(SetSendWithoutCodecs);
859WEBRTC_BASE_TEST(SetSendSetsTransportBufferSizes);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000860
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000861WEBRTC_BASE_TEST(GetStats);
862WEBRTC_BASE_TEST(GetStatsMultipleRecvStreams);
863WEBRTC_BASE_TEST(GetStatsMultipleSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000864
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000865WEBRTC_BASE_TEST(SetSendBandwidth);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000866
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000867WEBRTC_BASE_TEST(SetSendSsrc);
868WEBRTC_BASE_TEST(SetSendSsrcAfterSetCodecs);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000869
nisse08582ff2016-02-04 01:24:52 -0800870WEBRTC_BASE_TEST(SetSink);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000871
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000872WEBRTC_BASE_TEST(AddRemoveSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000873
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000874WEBRTC_BASE_TEST(SimulateConference);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000875
Alejandro Luebs947c02d2016-06-15 15:39:46 -0700876WEBRTC_DISABLED_BASE_TEST(AddRemoveCapturer);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000877
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000878WEBRTC_BASE_TEST(RemoveCapturerWithoutAdd);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000879
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000880WEBRTC_BASE_TEST(AddRemoveCapturerMultipleSources);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000881
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000882WEBRTC_BASE_TEST(RejectEmptyStreamParams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000883
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +0000884WEBRTC_BASE_TEST(MultipleSendStreams);
885
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000886TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Vga) {
magjed509e4fe2016-11-18 01:34:11 -0800887 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000888}
889
890TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Qvga) {
magjed509e4fe2016-11-18 01:34:11 -0800891 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000892}
893
894TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8SvcQqvga) {
magjed509e4fe2016-11-18 01:34:11 -0800895 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000896}
897
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000898TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) {
Peter Boströmd1f584b2016-04-20 16:31:53 +0200899 // Set a high bitrate to not be downscaled by VP8 due to low initial start
900 // bitrates. This currently happens at <250k, and two streams sharing 300k
901 // initially will use QVGA instead of VGA.
902 // TODO(pbos): Set up the quality scaler so that both senders reliably start
903 // at QVGA, then verify that instead.
magjed509e4fe2016-11-18 01:34:11 -0800904 cricket::VideoCodec codec = GetEngineCodec("VP8");
Peter Boströmd1f584b2016-04-20 16:31:53 +0200905 codec.params[kCodecParamStartBitrate] = "1000000";
906 Base::TwoStreamsSendAndReceive(codec);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000907}
908
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200909class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000910 public:
stefanc1aeaf02015-10-15 07:26:07 -0700911 WebRtcVideoChannel2Test() : WebRtcVideoChannel2Test("") {}
912 explicit WebRtcVideoChannel2Test(const char* field_trials)
913 : WebRtcVideoEngine2Test(field_trials), last_ssrc_(0) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000914 void SetUp() override {
skvlad11a9cbf2016-10-07 11:53:05 -0700915 fake_call_.reset(new FakeCall(webrtc::Call::Config(&event_log_)));
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200916 engine_.Init();
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200917 channel_.reset(
nisse51542be2016-02-12 02:27:06 -0800918 engine_.CreateChannel(fake_call_.get(), MediaConfig(), VideoOptions()));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000919 last_ssrc_ = 123;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200920 send_parameters_.codecs = engine_.codecs();
921 recv_parameters_.codecs = engine_.codecs();
922 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000923 }
924
925 protected:
926 FakeVideoSendStream* AddSendStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000927 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000928 }
929
930 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000931 size_t num_streams = fake_call_->GetVideoSendStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000932 EXPECT_TRUE(channel_->AddSendStream(sp));
933 std::vector<FakeVideoSendStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000934 fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000935 EXPECT_EQ(num_streams + 1, streams.size());
936 return streams[streams.size() - 1];
937 }
938
939 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000940 return fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000941 }
942
943 FakeVideoReceiveStream* AddRecvStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000944 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000945 }
946
947 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000948 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000949 EXPECT_TRUE(channel_->AddRecvStream(sp));
950 std::vector<FakeVideoReceiveStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000951 fake_call_->GetVideoReceiveStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000952 EXPECT_EQ(num_streams + 1, streams.size());
953 return streams[streams.size() - 1];
954 }
955
pbos@webrtc.org00873182014-11-25 14:03:34 +0000956 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
957 int expected_min_bitrate_bps,
958 const char* start_bitrate_kbps,
959 int expected_start_bitrate_bps,
960 const char* max_bitrate_kbps,
961 int expected_max_bitrate_bps) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200962 auto& codecs = send_parameters_.codecs;
963 codecs.clear();
magjed509e4fe2016-11-18 01:34:11 -0800964 codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org00873182014-11-25 14:03:34 +0000965 codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps;
966 codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps;
967 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200968 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000969
pbos@webrtc.org00873182014-11-25 14:03:34 +0000970 EXPECT_EQ(expected_min_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +0100971 fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +0000972 EXPECT_EQ(expected_start_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +0100973 fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +0000974 EXPECT_EQ(expected_max_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +0100975 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000976 }
977
isheriff6f8d6862016-05-26 11:24:55 -0700978 void TestSetSendRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000979 // Enable extension.
980 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200981 cricket::VideoSendParameters parameters = send_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -0700982 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200983 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000984 FakeVideoSendStream* send_stream =
985 AddSendStream(cricket::StreamParams::CreateLegacy(123));
986
987 // Verify the send extension id.
988 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
989 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -0700990 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000991 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200992 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000993 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
994 // receivers.
995 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
996 ->GetConfig()
997 .rtp.extensions.empty());
998
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000999 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001000 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001001 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1002 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001003 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
1004
1005 // Verify that adding receive RTP header extensions adds them for existing
1006 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001007 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001008 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001009 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1010 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001011 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001012 }
1013
isheriff6f8d6862016-05-26 11:24:55 -07001014 void TestSetRecvRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001015 // Enable extension.
1016 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001017 cricket::VideoRecvParameters parameters = recv_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07001018 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001019 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001020
1021 FakeVideoReceiveStream* recv_stream =
1022 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1023
1024 // Verify the recv extension id.
1025 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1026 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001027 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001028 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001029 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001030
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001031 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
1032 // senders.
1033 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
1034 ->GetConfig()
1035 .rtp.extensions.empty());
1036
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001037 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001038 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001039 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
1040 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001041 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
1042
1043 // Verify that adding receive RTP header extensions adds them for existing
1044 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001045 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001046 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001047 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1048 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001049 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001050 }
1051
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001052 void TestExtensionFilter(const std::vector<std::string>& extensions,
1053 const std::string& expected_extension) {
1054 cricket::VideoSendParameters parameters = send_parameters_;
1055 int expected_id = -1;
1056 int id = 1;
1057 for (const std::string& extension : extensions) {
1058 if (extension == expected_extension)
1059 expected_id = id;
isheriff6f8d6862016-05-26 11:24:55 -07001060 parameters.extensions.push_back(RtpExtension(extension, id++));
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001061 }
1062 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1063 FakeVideoSendStream* send_stream =
1064 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1065
1066 // Verify that only one of them has been set, and that it is the one with
1067 // highest priority (transport sequence number).
1068 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1069 EXPECT_EQ(expected_id, send_stream->GetConfig().rtp.extensions[0].id);
1070 EXPECT_EQ(expected_extension,
isheriff6f8d6862016-05-26 11:24:55 -07001071 send_stream->GetConfig().rtp.extensions[0].uri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001072 }
1073
Erik Språngefbde372015-04-29 16:21:28 +02001074 void TestCpuAdaptation(bool enable_overuse, bool is_screenshare);
Peter Boström3548dd22015-05-22 18:48:36 +02001075 void TestReceiverLocalSsrcConfiguration(bool receiver_first);
magjed509e4fe2016-11-18 01:34:11 -08001076 void TestReceiveUnsignaledSsrcPacket(uint8_t payload_type,
1077 bool expect_created_receive_stream);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001078
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001079 FakeVideoSendStream* SetDenoisingOption(
nisse05103312016-03-16 02:22:50 -07001080 uint32_t ssrc,
nisse0db023a2016-03-01 04:29:59 -08001081 cricket::FakeVideoCapturer* capturer,
1082 bool enabled) {
nisse05103312016-03-16 02:22:50 -07001083 cricket::VideoOptions options;
1084 options.video_noise_reduction = rtc::Optional<bool>(enabled);
deadbeef5a4a75a2016-06-02 16:23:38 -07001085 EXPECT_TRUE(channel_->SetVideoSend(ssrc, true, &options, capturer));
nisse0db023a2016-03-01 04:29:59 -08001086 // Options only take effect on the next frame.
1087 EXPECT_TRUE(capturer->CaptureFrame());
1088
Erik Språng143cec12015-04-28 10:01:41 +02001089 return fake_call_->GetVideoSendStreams().back();
1090 }
1091
Peter Boström2feafdb2015-09-09 14:32:14 +02001092 FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) {
1093 const int kRtxSsrcOffset = 0xDEADBEEF;
Erik Språng143cec12015-04-28 10:01:41 +02001094 last_ssrc_ += 3;
Peter Boström2feafdb2015-09-09 14:32:14 +02001095 std::vector<uint32_t> ssrcs;
1096 std::vector<uint32_t> rtx_ssrcs;
1097 uint32_t num_streams = enabled ? 3 : 1;
1098 for (uint32_t i = 0; i < num_streams; ++i) {
1099 uint32_t ssrc = last_ssrc_ + i;
1100 ssrcs.push_back(ssrc);
1101 if (with_rtx) {
1102 rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset);
1103 }
Erik Språng143cec12015-04-28 10:01:41 +02001104 }
Peter Boström2feafdb2015-09-09 14:32:14 +02001105 if (with_rtx) {
1106 return AddSendStream(
1107 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1108 }
1109 return AddSendStream(CreateSimStreamParams("cname", ssrcs));
Erik Språng143cec12015-04-28 10:01:41 +02001110 }
1111
perkjfa10b552016-10-02 23:45:26 -07001112 int GetMaxEncoderBitrate() {
skvladdc1c62c2016-03-16 19:07:43 -07001113 std::vector<FakeVideoSendStream*> streams =
1114 fake_call_->GetVideoSendStreams();
perkjfa10b552016-10-02 23:45:26 -07001115 EXPECT_EQ(1u, streams.size());
skvladdc1c62c2016-03-16 19:07:43 -07001116 FakeVideoSendStream* stream = streams[streams.size() - 1];
perkjfa10b552016-10-02 23:45:26 -07001117 EXPECT_EQ(1, stream->GetEncoderConfig().number_of_streams);
1118 return stream->GetVideoStreams()[0].max_bitrate_bps;
skvladdc1c62c2016-03-16 19:07:43 -07001119 }
1120
perkjfa10b552016-10-02 23:45:26 -07001121 void SetAndExpectMaxBitrate(int global_max,
skvladdc1c62c2016-03-16 19:07:43 -07001122 int stream_max,
1123 int expected_encoder_bitrate) {
1124 VideoSendParameters limited_send_params = send_parameters_;
1125 limited_send_params.max_bandwidth_bps = global_max;
1126 EXPECT_TRUE(channel_->SetSendParameters(limited_send_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001127 webrtc::RtpParameters parameters =
1128 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07001129 EXPECT_EQ(1UL, parameters.encodings.size());
1130 parameters.encodings[0].max_bitrate_bps = stream_max;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001131 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07001132 // Read back the parameteres and verify they have the correct value
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001133 parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07001134 EXPECT_EQ(1UL, parameters.encodings.size());
1135 EXPECT_EQ(stream_max, parameters.encodings[0].max_bitrate_bps);
1136 // Verify that the new value propagated down to the encoder
perkjfa10b552016-10-02 23:45:26 -07001137 EXPECT_EQ(expected_encoder_bitrate, GetMaxEncoderBitrate());
skvladdc1c62c2016-03-16 19:07:43 -07001138 }
1139
kwiberg686a8ef2016-02-26 03:00:35 -08001140 std::unique_ptr<FakeCall> fake_call_;
1141 std::unique_ptr<VideoMediaChannel> channel_;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001142 cricket::VideoSendParameters send_parameters_;
1143 cricket::VideoRecvParameters recv_parameters_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001144 uint32_t last_ssrc_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001145};
1146
pbos8fc7fa72015-07-15 08:02:58 -07001147TEST_F(WebRtcVideoChannel2Test, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02001148 const uint32_t kVideoSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07001149 const std::string kSyncLabel = "AvSyncLabel";
1150
1151 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc);
1152 sp.sync_label = kSyncLabel;
1153 EXPECT_TRUE(channel_->AddRecvStream(sp));
1154
1155 EXPECT_EQ(1, fake_call_->GetVideoReceiveStreams().size());
1156 EXPECT_EQ(kSyncLabel,
1157 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group)
1158 << "SyncGroup should be set based on sync_label";
1159}
1160
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001161TEST_F(WebRtcVideoChannel2Test, RecvStreamWithSimAndRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001162 cricket::VideoSendParameters parameters;
1163 parameters.codecs = engine_.codecs();
1164 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001165 EXPECT_TRUE(channel_->SetSend(true));
nisse4b4dc862016-02-17 05:25:36 -08001166 parameters.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001167 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001168
1169 // Send side.
Peter Boström0c4e06b2015-10-07 12:23:21 +02001170 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
1171 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001172 FakeVideoSendStream* send_stream = AddSendStream(
1173 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1174
1175 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
1176 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
1177 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
1178
1179 // Receiver side.
1180 FakeVideoReceiveStream* recv_stream = AddRecvStream(
1181 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
Peter Boströmd8b01092016-05-12 16:44:36 +02001182 EXPECT_FALSE(recv_stream->GetConfig().rtp.rtx.empty());
1183 EXPECT_EQ(recv_stream->GetConfig().decoders.size(),
1184 recv_stream->GetConfig().rtp.rtx.size())
1185 << "RTX should be mapped for all decoders/payload types.";
1186 for (const auto& kv : recv_stream->GetConfig().rtp.rtx) {
1187 EXPECT_EQ(rtx_ssrcs[0], kv.second.ssrc);
1188 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001189}
1190
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001191TEST_F(WebRtcVideoChannel2Test, RecvStreamWithRtx) {
1192 // Setup one channel with an associated RTX stream.
1193 cricket::StreamParams params =
1194 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
1195 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
1196 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001197 EXPECT_EQ(kRtxSsrcs1[0],
1198 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001199}
1200
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001201TEST_F(WebRtcVideoChannel2Test, RecvStreamNoRtx) {
1202 // Setup one channel without an associated RTX stream.
1203 cricket::StreamParams params =
1204 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
1205 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
1206 ASSERT_TRUE(recv_stream->GetConfig().rtp.rtx.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001207}
1208
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001209TEST_F(WebRtcVideoChannel2Test, NoHeaderExtesionsByDefault) {
1210 FakeVideoSendStream* send_stream =
1211 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
1212 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
1213
1214 FakeVideoReceiveStream* recv_stream =
1215 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
1216 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001217}
1218
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001219// Test support for RTP timestamp offset header extension.
1220TEST_F(WebRtcVideoChannel2Test, SendRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001221 TestSetSendRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001222}
isheriff6f8d6862016-05-26 11:24:55 -07001223
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001224TEST_F(WebRtcVideoChannel2Test, RecvRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001225 TestSetRecvRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001226}
1227
1228// Test support for absolute send time header extension.
1229TEST_F(WebRtcVideoChannel2Test, SendAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001230 TestSetSendRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001231}
isheriff6f8d6862016-05-26 11:24:55 -07001232
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001233TEST_F(WebRtcVideoChannel2Test, RecvAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001234 TestSetRecvRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001235}
1236
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001237TEST_F(WebRtcVideoChannel2Test, FiltersExtensionsPicksTransportSeqNum) {
1238 // Enable three redundant extensions.
1239 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07001240 extensions.push_back(RtpExtension::kAbsSendTimeUri);
1241 extensions.push_back(RtpExtension::kTimestampOffsetUri);
1242 extensions.push_back(RtpExtension::kTransportSequenceNumberUri);
1243 TestExtensionFilter(extensions, RtpExtension::kTransportSequenceNumberUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001244}
1245
1246TEST_F(WebRtcVideoChannel2Test, FiltersExtensionsPicksAbsSendTime) {
1247 // Enable two redundant extensions.
1248 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07001249 extensions.push_back(RtpExtension::kAbsSendTimeUri);
1250 extensions.push_back(RtpExtension::kTimestampOffsetUri);
1251 TestExtensionFilter(extensions, RtpExtension::kAbsSendTimeUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001252}
1253
stefanc1aeaf02015-10-15 07:26:07 -07001254// Test support for transport sequence number header extension.
Stefan Holmer06a5e1a2016-09-02 12:36:49 +02001255TEST_F(WebRtcVideoChannel2Test, SendTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001256 TestSetSendRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07001257}
Stefan Holmer06a5e1a2016-09-02 12:36:49 +02001258TEST_F(WebRtcVideoChannel2Test, RecvTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001259 TestSetRecvRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07001260}
1261
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001262// Test support for video rotation header extension.
1263TEST_F(WebRtcVideoChannel2Test, SendVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001264 TestSetSendRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001265}
1266TEST_F(WebRtcVideoChannel2Test, RecvVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001267 TestSetRecvRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001268}
1269
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001270TEST_F(WebRtcVideoChannel2Test, IdenticalSendExtensionsDoesntRecreateStream) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001271 const int kAbsSendTimeId = 1;
1272 const int kVideoRotationId = 2;
isheriff6f8d6862016-05-26 11:24:55 -07001273 send_parameters_.extensions.push_back(
1274 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
1275 send_parameters_.extensions.push_back(
1276 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001277
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001278 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001279 FakeVideoSendStream* send_stream =
1280 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1281
1282 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001283 ASSERT_EQ(2u, send_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001284
1285 // Setting the same extensions (even if in different order) shouldn't
1286 // reallocate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001287 std::reverse(send_parameters_.extensions.begin(),
1288 send_parameters_.extensions.end());
1289 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001290
1291 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1292
1293 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001294 send_parameters_.extensions.resize(1);
1295 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001296
1297 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
1298}
1299
1300TEST_F(WebRtcVideoChannel2Test, IdenticalRecvExtensionsDoesntRecreateStream) {
1301 const int kTOffsetId = 1;
1302 const int kAbsSendTimeId = 2;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001303 const int kVideoRotationId = 3;
isheriff6f8d6862016-05-26 11:24:55 -07001304 recv_parameters_.extensions.push_back(
1305 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
1306 recv_parameters_.extensions.push_back(
1307 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
1308 recv_parameters_.extensions.push_back(
1309 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001310
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001311 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Peter Boström54be3e02015-05-25 15:04:24 +02001312 FakeVideoReceiveStream* recv_stream =
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001313 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1314
1315 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Peter Boström54be3e02015-05-25 15:04:24 +02001316 ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001317
1318 // Setting the same extensions (even if in different order) shouldn't
1319 // reallocate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001320 std::reverse(recv_parameters_.extensions.begin(),
1321 recv_parameters_.extensions.end());
1322 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001323
1324 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
1325
1326 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001327 recv_parameters_.extensions.resize(1);
1328 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001329
1330 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
1331}
1332
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001333TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001334 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001335 const int kUnsupportedId = 1;
1336 const int kTOffsetId = 2;
1337
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001338 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001339 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001340 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001341 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001342 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001343 FakeVideoSendStream* send_stream =
1344 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1345
1346 // Only timestamp offset extension is set to send stream,
1347 // unsupported rtp extension is ignored.
1348 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07001349 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
1350 send_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001351}
1352
1353TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001354 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001355 const int kUnsupportedId = 1;
1356 const int kTOffsetId = 2;
1357
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001358 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001359 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001360 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001361 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001362 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001363 FakeVideoReceiveStream* recv_stream =
1364 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1365
1366 // Only timestamp offset extension is set to receive stream,
1367 // unsupported rtp extension is ignored.
1368 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07001369 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
1370 recv_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001371}
1372
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001373TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02001374 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00001375 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07001376 send_parameters_.extensions.push_back(
1377 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001378 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001379 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1380 }
1381}
1382
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001383TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02001384 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00001385 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07001386 recv_parameters_.extensions.push_back(
1387 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001388 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001389 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1390 }
1391}
1392
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001393TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001394 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001395 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001396 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001397 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001398 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001399 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001400
1401 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001402 send_parameters_.extensions.clear();
1403 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001404 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001405 send_parameters_.extensions.push_back(send_parameters_.extensions.back());
1406 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001407}
1408
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001409TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001410 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001411 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001412 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001413 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001414 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001415 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001416
1417 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001418 recv_parameters_.extensions.clear();
1419 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001420 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001421 recv_parameters_.extensions.push_back(recv_parameters_.extensions.back());
1422 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001423}
1424
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001425TEST_F(WebRtcVideoChannel2Test, AddRecvStreamOnlyUsesOneReceiveStream) {
1426 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001427 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001428}
1429
Peter Boströmd7da1202015-06-05 14:09:38 +02001430TEST_F(WebRtcVideoChannel2Test, RtcpIsCompoundByDefault) {
1431 FakeVideoReceiveStream* stream = AddRecvStream();
pbosda903ea2015-10-02 02:36:56 -07001432 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream->GetConfig().rtp.rtcp_mode);
Peter Boströmd7da1202015-06-05 14:09:38 +02001433}
1434
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001435TEST_F(WebRtcVideoChannel2Test, RembIsEnabledByDefault) {
1436 FakeVideoReceiveStream* stream = AddRecvStream();
1437 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001438}
1439
stefan43edf0f2015-11-20 18:05:48 -08001440TEST_F(WebRtcVideoChannel2Test, TransportCcIsEnabledByDefault) {
1441 FakeVideoReceiveStream* stream = AddRecvStream();
1442 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1443}
1444
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001445TEST_F(WebRtcVideoChannel2Test, RembCanBeEnabledAndDisabled) {
1446 FakeVideoReceiveStream* stream = AddRecvStream();
1447 EXPECT_TRUE(stream->GetConfig().rtp.remb);
1448
Peter Boström126c03e2015-05-11 12:48:12 +02001449 // Verify that REMB is turned off when send(!) codecs without REMB are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001450 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001451 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001452 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1453 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001454 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001455 EXPECT_FALSE(stream->GetConfig().rtp.remb);
1456
1457 // Verify that REMB is turned on when setting default codecs since the
1458 // default codecs have REMB enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001459 parameters.codecs = engine_.codecs();
1460 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001461 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001462 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001463}
1464
stefan43edf0f2015-11-20 18:05:48 -08001465TEST_F(WebRtcVideoChannel2Test, TransportCcCanBeEnabledAndDisabled) {
1466 FakeVideoReceiveStream* stream = AddRecvStream();
1467 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1468
1469 // Verify that transport cc feedback is turned off when send(!) codecs without
1470 // transport cc feedback are set.
1471 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001472 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
stefan43edf0f2015-11-20 18:05:48 -08001473 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1474 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1475 stream = fake_call_->GetVideoReceiveStreams()[0];
1476 EXPECT_FALSE(stream->GetConfig().rtp.transport_cc);
1477
1478 // Verify that transport cc feedback is turned on when setting default codecs
1479 // since the default codecs have transport cc feedback enabled.
1480 parameters.codecs = engine_.codecs();
1481 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1482 stream = fake_call_->GetVideoReceiveStreams()[0];
1483 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1484}
1485
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001486TEST_F(WebRtcVideoChannel2Test, NackIsEnabledByDefault) {
1487 VerifyCodecHasDefaultFeedbackParams(default_codec_);
1488
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001489 cricket::VideoSendParameters parameters;
1490 parameters.codecs = engine_.codecs();
1491 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org19864742014-05-30 07:35:47 +00001492 EXPECT_TRUE(channel_->SetSend(true));
1493
1494 // Send side.
1495 FakeVideoSendStream* send_stream =
1496 AddSendStream(cricket::StreamParams::CreateLegacy(1));
1497 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1498
1499 // Receiver side.
1500 FakeVideoReceiveStream* recv_stream =
1501 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
1502 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1503
1504 // Nack history size should match between sender and receiver.
1505 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
1506 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001507}
1508
Peter Boström67c9df72015-05-11 14:34:58 +02001509TEST_F(WebRtcVideoChannel2Test, NackCanBeEnabledAndDisabled) {
Peter Boström67c9df72015-05-11 14:34:58 +02001510 FakeVideoSendStream* send_stream = AddSendStream();
Peter Boström3548dd22015-05-22 18:48:36 +02001511 FakeVideoReceiveStream* recv_stream = AddRecvStream();
Peter Boström67c9df72015-05-11 14:34:58 +02001512
1513 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1514 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1515
1516 // Verify that NACK is turned off when send(!) codecs without NACK are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001517 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001518 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001519 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1520 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02001521 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1522 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
1523 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001524 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
1525
Peter Boström67c9df72015-05-11 14:34:58 +02001526 // Verify that NACK is turned on when setting default codecs since the
1527 // default codecs have NACK enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001528 parameters.codecs = engine_.codecs();
1529 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02001530 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1531 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1532 send_stream = fake_call_->GetVideoSendStreams()[0];
1533 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001534}
1535
Peter Boströme7ba0862016-03-12 00:02:28 +01001536// This test verifies that new frame sizes reconfigures encoders even though not
1537// (yet) sending. The purpose of this is to permit encoding as quickly as
1538// possible once we start sending. Likely the frames being input are from the
1539// same source that will be sent later, which just means that we're ready
1540// earlier.
1541TEST_F(WebRtcVideoChannel2Test, ReconfiguresEncodersWhenNotSending) {
1542 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001543 parameters.codecs.push_back(GetEngineCodec("VP8"));
Peter Boströme7ba0862016-03-12 00:02:28 +01001544 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1545 channel_->SetSend(false);
1546
1547 FakeVideoSendStream* stream = AddSendStream();
1548
perkjfa10b552016-10-02 23:45:26 -07001549 // No frames entered.
Peter Boströme7ba0862016-03-12 00:02:28 +01001550 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07001551 EXPECT_EQ(0u, streams[0].width);
1552 EXPECT_EQ(0u, streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01001553
1554 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07001555 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
perkj26752742016-10-24 01:21:16 -07001556 VideoFormat capture_format = capturer.GetSupportedFormats()->front();
1557 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format));
Peter Boströme7ba0862016-03-12 00:02:28 +01001558 EXPECT_TRUE(capturer.CaptureFrame());
1559
1560 // Frame entered, should be reconfigured to new dimensions.
1561 streams = stream->GetVideoStreams();
perkj26752742016-10-24 01:21:16 -07001562 EXPECT_EQ(capture_format.width, streams[0].width);
1563 EXPECT_EQ(capture_format.height, streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01001564
deadbeef5a4a75a2016-06-02 16:23:38 -07001565 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boströme7ba0862016-03-12 00:02:28 +01001566}
1567
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001568TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) {
1569 static const int kScreenshareMinBitrateKbps = 800;
magjed509e4fe2016-11-18 01:34:11 -08001570 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001571 cricket::VideoSendParameters parameters;
1572 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001573 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001574 AddSendStream();
1575
deadbeef5a4a75a2016-06-02 16:23:38 -07001576 cricket::FakeVideoCapturer capturer;
nisse05103312016-03-16 02:22:50 -07001577 VideoOptions min_bitrate_options;
1578 min_bitrate_options.screencast_min_bitrate_kbps =
1579 rtc::Optional<int>(kScreenshareMinBitrateKbps);
deadbeef5a4a75a2016-06-02 16:23:38 -07001580 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &min_bitrate_options,
1581 &capturer));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001582 cricket::VideoFormat capture_format_hd =
1583 capturer.GetSupportedFormats()->front();
1584 EXPECT_EQ(1280, capture_format_hd.width);
1585 EXPECT_EQ(720, capture_format_hd.height);
1586 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1587
1588 EXPECT_TRUE(channel_->SetSend(true));
1589
1590 EXPECT_TRUE(capturer.CaptureFrame());
1591 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1592 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1593
1594 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1595
1596 // Verify non-screencast settings.
perkj26091b12016-09-01 01:17:40 -07001597 webrtc::VideoEncoderConfig encoder_config =
1598 send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02001599 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001600 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07001601 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
1602 EXPECT_EQ(capture_format_hd.width, streams.front().width);
1603 EXPECT_EQ(capture_format_hd.height, streams.front().height);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001604 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
1605 << "Non-screenshare shouldn't use min-transmit bitrate.";
1606
deadbeef5a4a75a2016-06-02 16:23:38 -07001607 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkj2d5f0912016-02-29 00:04:41 -08001608 // Removing a capturer triggers a black frame to be sent.
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001609 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
nisse05103312016-03-16 02:22:50 -07001610 VideoOptions screencast_options;
1611 screencast_options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001612 EXPECT_TRUE(
1613 channel_->SetVideoSend(last_ssrc_, true, &screencast_options, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08001614 EXPECT_TRUE(capturer.CaptureFrame());
Niels Möller60653ba2016-03-02 11:41:36 +01001615 // Send stream not recreated after option change.
1616 ASSERT_EQ(send_stream, fake_call_->GetVideoSendStreams().front());
perkj2d5f0912016-02-29 00:04:41 -08001617 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001618
1619 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07001620 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02001621 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001622 encoder_config.content_type);
1623 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
1624 encoder_config.min_transmit_bitrate_bps);
1625
perkjfa10b552016-10-02 23:45:26 -07001626 streams = send_stream->GetVideoStreams();
1627 EXPECT_EQ(capture_format_hd.width, streams.front().width);
1628 EXPECT_EQ(capture_format_hd.height, streams.front().height);
1629 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
deadbeef5a4a75a2016-06-02 16:23:38 -07001630 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001631}
1632
Niels Möller60653ba2016-03-02 11:41:36 +01001633TEST_F(WebRtcVideoChannel2Test, NoRecreateStreamForScreencast) {
1634 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
1635 ASSERT_TRUE(
1636 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1637 EXPECT_TRUE(channel_->SetSend(true));
1638
1639 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07001640 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001641 EXPECT_EQ(cricket::CS_RUNNING,
1642 capturer.Start(capturer.GetSupportedFormats()->front()));
1643 EXPECT_TRUE(capturer.CaptureFrame());
1644
1645 ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1646 FakeVideoSendStream* stream = fake_call_->GetVideoSendStreams().front();
perkj26091b12016-09-01 01:17:40 -07001647 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
Niels Möller60653ba2016-03-02 11:41:36 +01001648 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
1649 encoder_config.content_type);
1650
1651 EXPECT_EQ(1, stream->GetNumberOfSwappedFrames());
1652
1653 /* Switch to screencast source. We expect a reconfigure of the
1654 * encoder, but no change of the send stream. */
1655 struct VideoOptions video_options;
1656 video_options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001657 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, &video_options, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001658
1659 EXPECT_TRUE(capturer.CaptureFrame());
1660 ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1661 ASSERT_EQ(stream, fake_call_->GetVideoSendStreams().front());
1662 EXPECT_EQ(2, stream->GetNumberOfSwappedFrames());
1663
perkj26091b12016-09-01 01:17:40 -07001664 encoder_config = stream->GetEncoderConfig().Copy();
Niels Möller60653ba2016-03-02 11:41:36 +01001665 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
1666 encoder_config.content_type);
1667
1668 /* Switch back. */
1669 video_options.is_screencast = rtc::Optional<bool>(false);
deadbeef5a4a75a2016-06-02 16:23:38 -07001670 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, &video_options, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001671
1672 EXPECT_TRUE(capturer.CaptureFrame());
1673 ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1674 ASSERT_EQ(stream, fake_call_->GetVideoSendStreams().front());
1675 EXPECT_EQ(3, stream->GetNumberOfSwappedFrames());
1676
perkj26091b12016-09-01 01:17:40 -07001677 encoder_config = stream->GetEncoderConfig().Copy();
Niels Möller60653ba2016-03-02 11:41:36 +01001678 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
1679 encoder_config.content_type);
1680
deadbeef5a4a75a2016-06-02 16:23:38 -07001681 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr, nullptr));
Niels Möller60653ba2016-03-02 11:41:36 +01001682}
1683
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001684TEST_F(WebRtcVideoChannel2Test,
1685 ConferenceModeScreencastConfiguresTemporalLayer) {
Erik Språng2c4c9142015-06-24 11:24:44 +02001686 static const int kConferenceScreencastTemporalBitrateBps =
1687 ScreenshareLayerConfig::GetDefault().tl0_bitrate_kbps * 1000;
nisse4b4dc862016-02-17 05:25:36 -08001688 send_parameters_.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001689 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001690
1691 AddSendStream();
nisse05103312016-03-16 02:22:50 -07001692 VideoOptions options;
1693 options.is_screencast = rtc::Optional<bool>(true);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001694 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07001695 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001696 cricket::VideoFormat capture_format_hd =
1697 capturer.GetSupportedFormats()->front();
1698 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1699
1700 EXPECT_TRUE(channel_->SetSend(true));
1701
1702 EXPECT_TRUE(capturer.CaptureFrame());
1703 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1704 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1705
perkj26091b12016-09-01 01:17:40 -07001706 webrtc::VideoEncoderConfig encoder_config =
1707 send_stream->GetEncoderConfig().Copy();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001708
1709 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07001710 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02001711 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001712 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07001713
1714 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
1715 ASSERT_EQ(1u, streams.size());
1716 ASSERT_EQ(1u, streams[0].temporal_layer_thresholds_bps.size());
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001717 EXPECT_EQ(kConferenceScreencastTemporalBitrateBps,
perkjfa10b552016-10-02 23:45:26 -07001718 streams[0].temporal_layer_thresholds_bps[0]);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001719
deadbeef5a4a75a2016-06-02 16:23:38 -07001720 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001721}
1722
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001723TEST_F(WebRtcVideoChannel2Test, SuspendBelowMinBitrateDisabledByDefault) {
1724 FakeVideoSendStream* stream = AddSendStream();
1725 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1726}
1727
nisse0db023a2016-03-01 04:29:59 -08001728TEST_F(WebRtcVideoChannel2Test, SetMediaConfigSuspendBelowMinBitrate) {
1729 MediaConfig media_config = MediaConfig();
1730 media_config.video.suspend_below_min_bitrate = true;
1731
1732 channel_.reset(
1733 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
1734
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001735 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001736
1737 FakeVideoSendStream* stream = AddSendStream();
1738 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
1739
nisse0db023a2016-03-01 04:29:59 -08001740 media_config.video.suspend_below_min_bitrate = false;
1741 channel_.reset(
1742 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
1743
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001744 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001745
nisse0db023a2016-03-01 04:29:59 -08001746 stream = AddSendStream();
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001747 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1748}
1749
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001750TEST_F(WebRtcVideoChannel2Test, Vp8DenoisingEnabledByDefault) {
1751 FakeVideoSendStream* stream = AddSendStream();
1752 webrtc::VideoCodecVP8 vp8_settings;
1753 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1754 EXPECT_TRUE(vp8_settings.denoisingOn);
1755}
1756
Erik Språng143cec12015-04-28 10:01:41 +02001757TEST_F(WebRtcVideoChannel2Test, VerifyVp8SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001758 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001759 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001760 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001761
Peter Boström2feafdb2015-09-09 14:32:14 +02001762 // Single-stream settings should apply with RTX as well (verifies that we
1763 // check number of regular SSRCs and not StreamParams::ssrcs which contains
1764 // both RTX and regular SSRCs).
1765 FakeVideoSendStream* stream = SetUpSimulcast(false, true);
Erik Språng143cec12015-04-28 10:01:41 +02001766
1767 cricket::FakeVideoCapturer capturer;
Erik Språng143cec12015-04-28 10:01:41 +02001768 EXPECT_EQ(cricket::CS_RUNNING,
1769 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07001770 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik Språng143cec12015-04-28 10:01:41 +02001771 channel_->SetSend(true);
1772
1773 EXPECT_TRUE(capturer.CaptureFrame());
1774
pbos4cba4eb2015-10-26 11:18:18 -07001775 webrtc::VideoCodecVP8 vp8_settings;
1776 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1777 EXPECT_TRUE(vp8_settings.denoisingOn)
1778 << "VP8 denoising should be on by default.";
1779
nisse05103312016-03-16 02:22:50 -07001780 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001781
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001782 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1783 EXPECT_FALSE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02001784 EXPECT_TRUE(vp8_settings.automaticResizeOn);
1785 EXPECT_TRUE(vp8_settings.frameDroppingOn);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001786
nisse05103312016-03-16 02:22:50 -07001787 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001788
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001789 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1790 EXPECT_TRUE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02001791 EXPECT_TRUE(vp8_settings.automaticResizeOn);
1792 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1793
deadbeef5a4a75a2016-06-02 16:23:38 -07001794 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boström2feafdb2015-09-09 14:32:14 +02001795 stream = SetUpSimulcast(true, false);
deadbeef5a4a75a2016-06-02 16:23:38 -07001796 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik Språng143cec12015-04-28 10:01:41 +02001797 channel_->SetSend(true);
1798 EXPECT_TRUE(capturer.CaptureFrame());
1799
1800 EXPECT_EQ(3, stream->GetVideoStreams().size());
1801 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1802 // Autmatic resize off when using simulcast.
1803 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1804 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1805
1806 // In screen-share mode, denoising is forced off and simulcast disabled.
nisse05103312016-03-16 02:22:50 -07001807 VideoOptions options;
1808 options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001809 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001810
nisse05103312016-03-16 02:22:50 -07001811 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001812
1813 EXPECT_EQ(1, stream->GetVideoStreams().size());
1814 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1815 EXPECT_FALSE(vp8_settings.denoisingOn);
1816 // Resizing and frame dropping always off for screen sharing.
1817 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1818 EXPECT_FALSE(vp8_settings.frameDroppingOn);
1819
nisse05103312016-03-16 02:22:50 -07001820 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
Erik Språng143cec12015-04-28 10:01:41 +02001821
1822 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1823 EXPECT_FALSE(vp8_settings.denoisingOn);
1824 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1825 EXPECT_FALSE(vp8_settings.frameDroppingOn);
1826
deadbeef5a4a75a2016-06-02 16:23:38 -07001827 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Erik Språng143cec12015-04-28 10:01:41 +02001828}
1829
deadbeef119760a2016-04-04 11:43:27 -07001830// Test that setting the same options doesn't result in the encoder being
1831// reconfigured.
1832TEST_F(WebRtcVideoChannel2Test, SetIdenticalOptionsDoesntReconfigureEncoder) {
1833 VideoOptions options;
1834 cricket::FakeVideoCapturer capturer;
1835
perkjfa10b552016-10-02 23:45:26 -07001836 AddSendStream();
deadbeef119760a2016-04-04 11:43:27 -07001837 EXPECT_EQ(cricket::CS_RUNNING,
1838 capturer.Start(capturer.GetSupportedFormats()->front()));
perkjfa10b552016-10-02 23:45:26 -07001839 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001840 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkjfa10b552016-10-02 23:45:26 -07001841 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1842 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1843
1844 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
deadbeef5a4a75a2016-06-02 16:23:38 -07001845 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
deadbeef119760a2016-04-04 11:43:27 -07001846 EXPECT_TRUE(capturer.CaptureFrame());
perkjfa10b552016-10-02 23:45:26 -07001847 // Expect 1 reconfigurations at this point from the initial configuration.
1848 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
deadbeef119760a2016-04-04 11:43:27 -07001849
1850 // Set the options one more time and expect no additional reconfigurations.
deadbeef5a4a75a2016-06-02 16:23:38 -07001851 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
perkjfa10b552016-10-02 23:45:26 -07001852 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
1853
1854 // Change |options| and expect 2 reconfigurations.
1855 options.is_screencast = rtc::Optional<bool>(true);
1856 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
deadbeef119760a2016-04-04 11:43:27 -07001857 EXPECT_EQ(2, send_stream->num_encoder_reconfigurations());
1858
deadbeef5a4a75a2016-06-02 16:23:38 -07001859 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
deadbeef119760a2016-04-04 11:43:27 -07001860}
1861
Erik Språng143cec12015-04-28 10:01:41 +02001862class Vp9SettingsTest : public WebRtcVideoChannel2Test {
1863 public:
asaperssonc5dabdd2016-03-21 04:15:50 -07001864 Vp9SettingsTest() : Vp9SettingsTest("") {}
1865 explicit Vp9SettingsTest(const char* field_trials)
1866 : WebRtcVideoChannel2Test(field_trials) {
magjed1e45cc62016-10-28 07:43:45 -07001867 encoder_factory_.AddSupportedVideoCodecType("VP9");
Erik Språng143cec12015-04-28 10:01:41 +02001868 }
1869 virtual ~Vp9SettingsTest() {}
1870
1871 protected:
1872 void SetUp() override {
1873 engine_.SetExternalEncoderFactory(&encoder_factory_);
1874
1875 WebRtcVideoChannel2Test::SetUp();
1876 }
1877
1878 void TearDown() override {
1879 // Remove references to encoder_factory_ since this will be destroyed
1880 // before channel_ and engine_.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001881 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
Erik Språng143cec12015-04-28 10:01:41 +02001882 }
1883
1884 cricket::FakeWebRtcVideoEncoderFactory encoder_factory_;
1885};
1886
1887TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001888 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001889 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001890 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Erik Språng143cec12015-04-28 10:01:41 +02001891
Peter Boström2feafdb2015-09-09 14:32:14 +02001892 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
Erik Språng143cec12015-04-28 10:01:41 +02001893
1894 cricket::FakeVideoCapturer capturer;
Erik Språng143cec12015-04-28 10:01:41 +02001895 EXPECT_EQ(cricket::CS_RUNNING,
1896 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07001897 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik Språng143cec12015-04-28 10:01:41 +02001898 channel_->SetSend(true);
1899
1900 EXPECT_TRUE(capturer.CaptureFrame());
1901
pbos4cba4eb2015-10-26 11:18:18 -07001902 webrtc::VideoCodecVP9 vp9_settings;
1903 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1904 EXPECT_FALSE(vp9_settings.denoisingOn)
1905 << "VP9 denoising should be off by default.";
1906
nisse05103312016-03-16 02:22:50 -07001907 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001908
Erik Språng143cec12015-04-28 10:01:41 +02001909 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1910 EXPECT_FALSE(vp9_settings.denoisingOn);
1911 // Frame dropping always on for real time video.
1912 EXPECT_TRUE(vp9_settings.frameDroppingOn);
1913
nisse05103312016-03-16 02:22:50 -07001914 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
Erik Språng143cec12015-04-28 10:01:41 +02001915
1916 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1917 EXPECT_TRUE(vp9_settings.denoisingOn);
1918 EXPECT_TRUE(vp9_settings.frameDroppingOn);
1919
1920 // In screen-share mode, denoising is forced off.
nisse05103312016-03-16 02:22:50 -07001921 VideoOptions options;
1922 options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001923 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08001924
nisse05103312016-03-16 02:22:50 -07001925 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001926
1927 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1928 EXPECT_FALSE(vp9_settings.denoisingOn);
1929 // Frame dropping always off for screen sharing.
1930 EXPECT_FALSE(vp9_settings.frameDroppingOn);
1931
nisse05103312016-03-16 02:22:50 -07001932 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001933
1934 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1935 EXPECT_FALSE(vp9_settings.denoisingOn);
1936 EXPECT_FALSE(vp9_settings.frameDroppingOn);
1937
deadbeef5a4a75a2016-06-02 16:23:38 -07001938 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001939}
1940
asaperssonc5dabdd2016-03-21 04:15:50 -07001941class Vp9SettingsTestWithFieldTrial : public Vp9SettingsTest {
1942 public:
brandtr468da7c2016-11-22 02:16:47 -08001943 explicit Vp9SettingsTestWithFieldTrial(const char* field_trials)
asaperssonc5dabdd2016-03-21 04:15:50 -07001944 : Vp9SettingsTest(field_trials) {}
1945
1946 protected:
1947 void VerifySettings(int num_spatial_layers, int num_temporal_layers) {
1948 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001949 parameters.codecs.push_back(GetEngineCodec("VP9"));
asaperssonc5dabdd2016-03-21 04:15:50 -07001950 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1951
1952 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
1953
1954 cricket::FakeVideoCapturer capturer;
1955 EXPECT_EQ(cricket::CS_RUNNING,
1956 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07001957 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
asaperssonc5dabdd2016-03-21 04:15:50 -07001958 channel_->SetSend(true);
1959
1960 EXPECT_TRUE(capturer.CaptureFrame());
1961
1962 webrtc::VideoCodecVP9 vp9_settings;
1963 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1964 EXPECT_EQ(num_spatial_layers, vp9_settings.numberOfSpatialLayers);
1965 EXPECT_EQ(num_temporal_layers, vp9_settings.numberOfTemporalLayers);
1966
deadbeef5a4a75a2016-06-02 16:23:38 -07001967 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
asaperssonc5dabdd2016-03-21 04:15:50 -07001968 }
1969};
1970
1971class Vp9SettingsTestWithNoFlag : public Vp9SettingsTestWithFieldTrial {
1972 public:
1973 Vp9SettingsTestWithNoFlag() : Vp9SettingsTestWithFieldTrial("") {}
1974};
1975
1976TEST_F(Vp9SettingsTestWithNoFlag, VerifySettings) {
1977 const int kNumSpatialLayers = 1;
1978 const int kNumTemporalLayers = 1;
1979 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
1980}
1981
1982class Vp9SettingsTestWithInvalidFlag : public Vp9SettingsTestWithFieldTrial {
1983 public:
1984 Vp9SettingsTestWithInvalidFlag()
1985 : Vp9SettingsTestWithFieldTrial("WebRTC-SupportVP9SVC/Default/") {}
1986};
1987
1988TEST_F(Vp9SettingsTestWithInvalidFlag, VerifySettings) {
1989 const int kNumSpatialLayers = 1;
1990 const int kNumTemporalLayers = 1;
1991 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
1992}
1993
1994class Vp9SettingsTestWith2SL3TLFlag : public Vp9SettingsTestWithFieldTrial {
1995 public:
1996 Vp9SettingsTestWith2SL3TLFlag()
1997 : Vp9SettingsTestWithFieldTrial(
1998 "WebRTC-SupportVP9SVC/EnabledByFlag_2SL3TL/") {}
1999};
2000
2001TEST_F(Vp9SettingsTestWith2SL3TLFlag, VerifySettings) {
2002 const int kNumSpatialLayers = 2;
2003 const int kNumTemporalLayers = 3;
2004 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
2005}
2006
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002007TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruse) {
Erik Språngefbde372015-04-29 16:21:28 +02002008 TestCpuAdaptation(true, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002009}
2010
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002011TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenDisabled) {
Erik Språngefbde372015-04-29 16:21:28 +02002012 TestCpuAdaptation(false, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002013}
2014
Erik Språngefbde372015-04-29 16:21:28 +02002015TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenScreensharing) {
2016 TestCpuAdaptation(true, true);
2017}
2018
perkj2d5f0912016-02-29 00:04:41 -08002019TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruseAndChangeResolution) {
magjed509e4fe2016-11-18 01:34:11 -08002020 cricket::VideoCodec codec = GetEngineCodec("VP8");
perkj2d5f0912016-02-29 00:04:41 -08002021 cricket::VideoSendParameters parameters;
2022 parameters.codecs.push_back(codec);
2023
2024 MediaConfig media_config = MediaConfig();
2025 channel_.reset(
2026 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
2027 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2028
2029 AddSendStream();
2030
2031 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002032 ASSERT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08002033 ASSERT_EQ(cricket::CS_RUNNING,
2034 capturer.Start(capturer.GetSupportedFormats()->front()));
2035 ASSERT_TRUE(channel_->SetSend(true));
2036
2037 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2038 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
perkj2d5f0912016-02-29 00:04:41 -08002039
2040 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2041 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2042 EXPECT_EQ(1280, send_stream->GetLastWidth());
2043 EXPECT_EQ(720, send_stream->GetLastHeight());
2044
2045 // Trigger overuse.
perkj803d97f2016-11-01 11:45:46 -07002046 rtc::VideoSinkWants wants;
2047 wants.max_pixel_count = rtc::Optional<int>(
2048 send_stream->GetLastWidth() * send_stream->GetLastHeight() - 1);
2049 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002050 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2051 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
2052 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2053 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2054
2055 // Trigger overuse again.
perkj803d97f2016-11-01 11:45:46 -07002056 wants.max_pixel_count = rtc::Optional<int>(
2057 send_stream->GetLastWidth() * send_stream->GetLastHeight() - 1);
2058 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002059 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2060 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
2061 EXPECT_EQ(1280 * 2 / 4, send_stream->GetLastWidth());
2062 EXPECT_EQ(720 * 2 / 4, send_stream->GetLastHeight());
2063
2064 // Change input resolution.
2065 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
perkj803d97f2016-11-01 11:45:46 -07002066 EXPECT_EQ(4, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002067 EXPECT_EQ(1284 / 2, send_stream->GetLastWidth());
2068 EXPECT_EQ(724 / 2, send_stream->GetLastHeight());
2069
2070 // Trigger underuse which should go back up in resolution.
perkj803d97f2016-11-01 11:45:46 -07002071 wants.max_pixel_count = rtc::Optional<int>();
2072 wants.max_pixel_count_step_up = rtc::Optional<int>(
2073 send_stream->GetLastWidth() * send_stream->GetLastHeight());
2074 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002075 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
perkj803d97f2016-11-01 11:45:46 -07002076 EXPECT_EQ(5, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002077 EXPECT_EQ(1284 * 3 / 4, send_stream->GetLastWidth());
2078 EXPECT_EQ(724 * 3 / 4, send_stream->GetLastHeight());
2079
2080 // Trigger underuse which should go back up in resolution.
perkj803d97f2016-11-01 11:45:46 -07002081 wants.max_pixel_count = rtc::Optional<int>();
2082 wants.max_pixel_count_step_up = rtc::Optional<int>(
2083 send_stream->GetLastWidth() * send_stream->GetLastHeight());
2084 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002085 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
perkj803d97f2016-11-01 11:45:46 -07002086 EXPECT_EQ(6, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002087 EXPECT_EQ(1284, send_stream->GetLastWidth());
2088 EXPECT_EQ(724, send_stream->GetLastHeight());
2089
deadbeef5a4a75a2016-06-02 16:23:38 -07002090 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkj2d5f0912016-02-29 00:04:41 -08002091}
2092
Per766ad3b2016-04-05 15:23:49 +02002093TEST_F(WebRtcVideoChannel2Test, PreviousAdaptationDoesNotApplyToScreenshare) {
magjed509e4fe2016-11-18 01:34:11 -08002094 cricket::VideoCodec codec = GetEngineCodec("VP8");
Per766ad3b2016-04-05 15:23:49 +02002095 cricket::VideoSendParameters parameters;
2096 parameters.codecs.push_back(codec);
2097
2098 MediaConfig media_config = MediaConfig();
2099 channel_.reset(
2100 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
2101 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2102
2103 AddSendStream();
2104
2105 cricket::FakeVideoCapturer capturer;
Per766ad3b2016-04-05 15:23:49 +02002106 ASSERT_EQ(cricket::CS_RUNNING,
2107 capturer.Start(capturer.GetSupportedFormats()->front()));
2108 ASSERT_TRUE(channel_->SetSend(true));
2109 cricket::VideoOptions camera_options;
perkj803d97f2016-11-01 11:45:46 -07002110 camera_options.is_screencast = rtc::Optional<bool>(false);
deadbeef5a4a75a2016-06-02 16:23:38 -07002111 channel_->SetVideoSend(last_ssrc_, true /* enable */, &camera_options,
2112 &capturer);
Per766ad3b2016-04-05 15:23:49 +02002113
2114 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2115 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
Per766ad3b2016-04-05 15:23:49 +02002116
2117 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2118 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2119 EXPECT_EQ(1280, send_stream->GetLastWidth());
2120 EXPECT_EQ(720, send_stream->GetLastHeight());
2121
2122 // Trigger overuse.
perkj803d97f2016-11-01 11:45:46 -07002123 rtc::VideoSinkWants wants;
2124 wants.max_pixel_count = rtc::Optional<int>(
2125 send_stream->GetLastWidth() * send_stream->GetLastHeight() - 1);
2126 send_stream->InjectVideoSinkWants(wants);
Per766ad3b2016-04-05 15:23:49 +02002127 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2128 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
2129 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2130 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2131
2132 // Switch to screen share. Expect no CPU adaptation.
2133 cricket::FakeVideoCapturer screen_share(true);
2134 ASSERT_EQ(cricket::CS_RUNNING,
2135 screen_share.Start(screen_share.GetSupportedFormats()->front()));
Per766ad3b2016-04-05 15:23:49 +02002136 cricket::VideoOptions screenshare_options;
2137 screenshare_options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07002138 channel_->SetVideoSend(last_ssrc_, true /* enable */, &screenshare_options,
2139 &screen_share);
Per766ad3b2016-04-05 15:23:49 +02002140 EXPECT_TRUE(screen_share.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
2141 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
2142 EXPECT_EQ(1284, send_stream->GetLastWidth());
2143 EXPECT_EQ(724, send_stream->GetLastHeight());
2144
2145 // Switch back to the normal capturer. Expect the frame to be CPU adapted.
deadbeef5a4a75a2016-06-02 16:23:38 -07002146 channel_->SetVideoSend(last_ssrc_, true /* enable */, &camera_options,
2147 &capturer);
Per766ad3b2016-04-05 15:23:49 +02002148 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2149 EXPECT_EQ(4, send_stream->GetNumberOfSwappedFrames());
2150 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2151 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2152
deadbeef5a4a75a2016-06-02 16:23:38 -07002153 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Per766ad3b2016-04-05 15:23:49 +02002154}
2155
Erik Språngefbde372015-04-29 16:21:28 +02002156void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse,
2157 bool is_screenshare) {
magjed509e4fe2016-11-18 01:34:11 -08002158 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002159 cricket::VideoSendParameters parameters;
2160 parameters.codecs.push_back(codec);
nisse51542be2016-02-12 02:27:06 -08002161
2162 MediaConfig media_config = MediaConfig();
Peter Boströme4328002015-04-14 22:45:29 +02002163 if (!enable_overuse) {
nisse0db023a2016-03-01 04:29:59 -08002164 media_config.video.enable_cpu_overuse_detection = false;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002165 }
nisse51542be2016-02-12 02:27:06 -08002166 channel_.reset(
2167 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
2168
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002169 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002170
2171 AddSendStream();
2172
deadbeef5a4a75a2016-06-02 16:23:38 -07002173 cricket::FakeVideoCapturer capturer;
nisse05103312016-03-16 02:22:50 -07002174 VideoOptions options;
2175 options.is_screencast = rtc::Optional<bool>(is_screenshare);
deadbeef5a4a75a2016-06-02 16:23:38 -07002176 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
perkj26752742016-10-24 01:21:16 -07002177 cricket::VideoFormat capture_format = capturer.GetSupportedFormats()->front();
2178 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002179
2180 EXPECT_TRUE(channel_->SetSend(true));
2181
solenberge5269742015-09-08 05:13:22 -07002182 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
perkj2d5f0912016-02-29 00:04:41 -08002183
perkj803d97f2016-11-01 11:45:46 -07002184 if (!enable_overuse || is_screenshare) {
2185 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
perkj2d5f0912016-02-29 00:04:41 -08002186
2187 EXPECT_TRUE(capturer.CaptureFrame());
2188 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2189
perkj26752742016-10-24 01:21:16 -07002190 EXPECT_EQ(capture_format.width, send_stream->GetLastWidth());
2191 EXPECT_EQ(capture_format.height, send_stream->GetLastHeight());
perkj2d5f0912016-02-29 00:04:41 -08002192
deadbeef5a4a75a2016-06-02 16:23:38 -07002193 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkj2d5f0912016-02-29 00:04:41 -08002194 return;
2195 }
2196
perkj803d97f2016-11-01 11:45:46 -07002197 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
2198 // Trigger overuse.
2199 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2200
2201 rtc::VideoSinkWants wants;
2202 wants.max_pixel_count =
2203 rtc::Optional<int>(capture_format.width * capture_format.height - 1);
2204 send_stream->InjectVideoSinkWants(wants);
2205
perkj2d5f0912016-02-29 00:04:41 -08002206 EXPECT_TRUE(capturer.CaptureFrame());
2207 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002208
2209 EXPECT_TRUE(capturer.CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -08002210 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002211
perkj803d97f2016-11-01 11:45:46 -07002212 EXPECT_LT(send_stream->GetLastWidth(), capture_format.width);
2213 EXPECT_LT(send_stream->GetLastHeight(), capture_format.height);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002214
2215 // Trigger underuse which should go back to normal resolution.
perkj803d97f2016-11-01 11:45:46 -07002216 wants.max_pixel_count = rtc::Optional<int>();
2217 wants.max_pixel_count_step_up = rtc::Optional<int>(
2218 send_stream->GetLastWidth() * send_stream->GetLastHeight());
2219 send_stream->InjectVideoSinkWants(wants);
2220
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002221 EXPECT_TRUE(capturer.CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -08002222 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002223
perkj26752742016-10-24 01:21:16 -07002224 EXPECT_EQ(capture_format.width, send_stream->GetLastWidth());
2225 EXPECT_EQ(capture_format.height, send_stream->GetLastHeight());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002226
deadbeef5a4a75a2016-06-02 16:23:38 -07002227 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002228}
2229
magjedb09b6602015-10-01 03:02:44 -07002230TEST_F(WebRtcVideoChannel2Test, EstimatesNtpStartTimeCorrectly) {
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002231 // Start at last timestamp to verify that wraparounds are estimated correctly.
2232 static const uint32_t kInitialTimestamp = 0xFFFFFFFFu;
2233 static const int64_t kInitialNtpTimeMs = 1247891230;
2234 static const int kFrameOffsetMs = 20;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002235 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002236
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002237 FakeVideoReceiveStream* stream = AddRecvStream();
2238 cricket::FakeVideoRenderer renderer;
nisse08582ff2016-02-04 01:24:52 -08002239 EXPECT_TRUE(channel_->SetSink(last_ssrc_, &renderer));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002240
nisse64ec8f82016-09-27 00:17:25 -07002241 webrtc::VideoFrame video_frame(CreateBlackFrameBuffer(4, 4),
2242 kInitialTimestamp, 0,
2243 webrtc::kVideoRotation_0);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002244 // Initial NTP time is not available on the first frame, but should still be
2245 // able to be estimated.
nisseeb83a1a2016-03-21 01:27:56 -07002246 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002247
2248 EXPECT_EQ(1, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002249
2250 // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which
2251 // triggers a constant-overflow warning, hence we're calculating it explicitly
2252 // here.
2253 video_frame.set_timestamp(kFrameOffsetMs * 90 - 1);
2254 video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs);
nisseeb83a1a2016-03-21 01:27:56 -07002255 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002256
2257 EXPECT_EQ(2, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002258
2259 // Verify that NTP time has been correctly deduced.
2260 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002261 ASSERT_TRUE(channel_->GetStats(&info));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002262 ASSERT_EQ(1u, info.receivers.size());
2263 EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002264}
2265
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002266TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002267 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002268
2269 VideoCodec codec;
2270 EXPECT_TRUE(channel_->GetSendCodec(&codec));
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00002271 EXPECT_TRUE(codec.Matches(engine_.codecs()[0]));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002272
2273 // Using a RTX setup to verify that the default RTX payload type is good.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002274 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
2275 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002276 FakeVideoSendStream* stream = AddSendStream(
2277 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
perkj26091b12016-09-01 01:17:40 -07002278 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002279
2280 // Make sure NACK and FEC are enabled on the correct payload types.
2281 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
magjed509e4fe2016-11-18 01:34:11 -08002282 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
2283 EXPECT_EQ(GetEngineCodec("red").id, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002284
2285 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
2286 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
Shao Changbine62202f2015-04-21 20:24:50 +08002287 VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002288 // TODO(juberti): Check RTCP, PLI, TMMBR.
2289}
2290
brandtr468da7c2016-11-22 02:16:47 -08002291// TODO(brandtr): Remove when FlexFEC _is_ exposed by default.
2292TEST_F(WebRtcVideoChannel2Test, FlexfecCodecWithoutSsrcNotExposedByDefault) {
2293 FakeVideoSendStream* stream = AddSendStream();
2294 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2295
2296 EXPECT_EQ(-1, config.rtp.flexfec.flexfec_payload_type);
2297}
2298
2299// TODO(brandtr): Remove when FlexFEC _is_ exposed by default.
2300TEST_F(WebRtcVideoChannel2Test, FlexfecCodecWithSsrcNotExposedByDefault) {
2301 FakeVideoSendStream* stream = AddSendStream(
2302 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2303 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2304
2305 EXPECT_EQ(-1, config.rtp.flexfec.flexfec_payload_type);
2306}
2307
2308// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
2309// tests that use this test fixture into the corresponding "non-field trial"
2310// tests.
2311class WebRtcVideoChannel2FlexfecTest : public WebRtcVideoChannel2Test {
2312 public:
2313 WebRtcVideoChannel2FlexfecTest()
2314 : WebRtcVideoChannel2Test("WebRTC-FlexFEC-03/Enabled/") {}
2315};
2316
2317// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2318// by default.
2319TEST_F(WebRtcVideoChannel2FlexfecTest, SetDefaultSendCodecsWithoutSsrc) {
2320 FakeVideoSendStream* stream = AddSendStream();
2321 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2322
2323 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
2324 config.rtp.flexfec.flexfec_payload_type);
2325 EXPECT_FALSE(config.rtp.flexfec.IsCompleteAndEnabled());
2326}
2327
2328// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2329// by default.
2330TEST_F(WebRtcVideoChannel2FlexfecTest, SetDefaultSendCodecsWithSsrc) {
2331 FakeVideoSendStream* stream = AddSendStream(
2332 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2333 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2334
2335 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
2336 config.rtp.flexfec.flexfec_payload_type);
2337 EXPECT_TRUE(config.rtp.flexfec.IsCompleteAndEnabled());
2338}
2339
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002340TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002341 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002342 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002343 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002344
2345 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07002346 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002347
brandtrb5f2c3f2016-10-04 23:28:39 -07002348 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type);
2349 EXPECT_EQ(-1, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002350}
2351
brandtr468da7c2016-11-22 02:16:47 -08002352// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2353// by default.
2354TEST_F(WebRtcVideoChannel2FlexfecTest, SetSendCodecsWithoutFec) {
2355 cricket::VideoSendParameters parameters;
2356 parameters.codecs.push_back(GetEngineCodec("VP8"));
2357 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2358
2359 FakeVideoSendStream* stream = AddSendStream();
2360 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2361
2362 EXPECT_EQ(-1, config.rtp.flexfec.flexfec_payload_type);
2363}
2364
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002365TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002366 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
magjed509e4fe2016-11-18 01:34:11 -08002367 const int kUnusedPayloadType = 127;
2368 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType));
2369
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002370 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002371 cricket::VideoCodec rtx_codec(kUnusedPayloadType, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002372 parameters.codecs.push_back(rtx_codec);
2373 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002374 << "RTX codec without associated payload type should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002375}
2376
2377TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002378 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
magjed509e4fe2016-11-18 01:34:11 -08002379 const int kUnusedPayloadType1 = 126;
2380 const int kUnusedPayloadType2 = 127;
2381 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
2382 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
2383 {
2384 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
2385 kUnusedPayloadType1, GetEngineCodec("VP8").id);
2386 cricket::VideoSendParameters parameters;
2387 parameters.codecs.push_back(GetEngineCodec("VP8"));
2388 parameters.codecs.push_back(rtx_codec);
2389 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2390 }
2391 {
2392 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
2393 kUnusedPayloadType1, kUnusedPayloadType2);
2394 cricket::VideoSendParameters parameters;
2395 parameters.codecs.push_back(GetEngineCodec("VP8"));
2396 parameters.codecs.push_back(rtx_codec);
2397 EXPECT_FALSE(channel_->SetSendParameters(parameters))
2398 << "RTX without matching video codec should be rejected.";
2399 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002400}
2401
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002402TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002403 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002404 parameters.codecs.push_back(GetEngineCodec("VP8"));
2405 parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002406 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002407
2408 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07002409 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002410
magjed509e4fe2016-11-18 01:34:11 -08002411 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002412
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002413 parameters.codecs.pop_back();
2414 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002415 stream = fake_call_->GetVideoSendStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08002416 ASSERT_TRUE(stream != nullptr);
perkj26091b12016-09-01 01:17:40 -07002417 config = stream->GetConfig().Copy();
brandtrb5f2c3f2016-10-04 23:28:39 -07002418 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08002419 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
2420}
2421
2422// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2423// by default.
2424TEST_F(WebRtcVideoChannel2FlexfecTest, SetSendCodecsWithoutFecDisablesFec) {
2425 cricket::VideoSendParameters parameters;
2426 parameters.codecs.push_back(GetEngineCodec("VP8"));
2427 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2428 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2429
2430 FakeVideoSendStream* stream = AddSendStream(
2431 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2432 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2433
2434 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
2435 config.rtp.flexfec.flexfec_payload_type);
2436 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.flexfec_ssrc);
2437 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
2438 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
2439
2440 parameters.codecs.pop_back();
2441 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2442 stream = fake_call_->GetVideoSendStreams()[0];
2443 ASSERT_TRUE(stream != nullptr);
2444 config = stream->GetConfig().Copy();
2445 EXPECT_EQ(-1, config.rtp.flexfec.flexfec_payload_type)
2446 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002447}
2448
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002449TEST_F(WebRtcVideoChannel2Test, SetSendCodecsChangesExistingStreams) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002450 cricket::VideoSendParameters parameters;
perkj26752742016-10-24 01:21:16 -07002451 cricket::VideoCodec codec(100, "VP8");
2452 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax);
2453 parameters.codecs.push_back(codec);
perkjfa10b552016-10-02 23:45:26 -07002454
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002455 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002456 channel_->SetSend(true);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002457
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002458 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002459 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002460 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002461
2462 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07002463 EXPECT_EQ(kDefaultQpMax, streams[0].max_qp);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002464
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002465 parameters.codecs.clear();
perkj26752742016-10-24 01:21:16 -07002466 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax + 1);
2467 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002468 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002469 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07002470 EXPECT_EQ(kDefaultQpMax + 1, streams[0].max_qp);
deadbeef5a4a75a2016-06-02 16:23:38 -07002471 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002472}
2473
pbos@webrtc.org00873182014-11-25 14:03:34 +00002474TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithBitrates) {
2475 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
2476 200000);
2477}
2478
pbos@webrtc.orga5f6fb52015-03-23 22:29:39 +00002479TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithHighMaxBitrate) {
2480 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
2481 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
2482 ASSERT_EQ(1u, streams.size());
2483 EXPECT_EQ(10000000, streams[0].max_bitrate_bps);
2484}
2485
pbos@webrtc.org00873182014-11-25 14:03:34 +00002486TEST_F(WebRtcVideoChannel2Test,
2487 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
2488 SetSendCodecsShouldWorkForBitrates(
2489 "", 0, "", -1, "", -1);
2490}
2491
2492TEST_F(WebRtcVideoChannel2Test, SetSendCodecsCapsMinAndStartBitrate) {
2493 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002494}
2495
2496TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectsMaxLessThanMinBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002497 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "300";
2498 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "200";
2499 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002500}
2501
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07002502// Test that when both the codec-specific bitrate params and max_bandwidth_bps
2503// are present in the same send parameters, the settings are combined correctly.
2504TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithBitratesAndMaxSendBandwidth) {
2505 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
2506 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
2507 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
2508 send_parameters_.max_bandwidth_bps = 400000;
2509 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2510 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2511 EXPECT_EQ(200000, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2512 // We expect max_bandwidth_bps to take priority, if set.
2513 EXPECT_EQ(400000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2514
2515 // Decrease max_bandwidth_bps.
2516 send_parameters_.max_bandwidth_bps = 350000;
2517 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2518 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2519 // Since the codec isn't changing, start_bitrate_bps should be -1.
2520 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2521 EXPECT_EQ(350000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2522
2523 // Now try again with the values flipped around.
2524 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
2525 send_parameters_.max_bandwidth_bps = 300000;
2526 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2527 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2528 EXPECT_EQ(200000, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2529 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2530
2531 // If we change the codec max, max_bandwidth_bps should still apply.
2532 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
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
pbos@webrtc.org00873182014-11-25 14:03:34 +00002539TEST_F(WebRtcVideoChannel2Test,
2540 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
2541 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
2542 200000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002543 send_parameters_.max_bandwidth_bps = 300000;
2544 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01002545 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002546 << "Setting max bitrate should keep previous min bitrate.";
Stefan Holmere5904162015-03-26 11:11:06 +01002547 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.start_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002548 << "Setting max bitrate should not reset start bitrate.";
Stefan Holmere5904162015-03-26 11:11:06 +01002549 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002550}
2551
2552TEST_F(WebRtcVideoChannel2Test, SetMaxSendBandwidthShouldBeRemovable) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002553 send_parameters_.max_bandwidth_bps = 300000;
2554 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01002555 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002556 // <= 0 means disable (infinite) max bitrate.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002557 send_parameters_.max_bandwidth_bps = 0;
2558 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01002559 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.max_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002560 << "Setting zero max bitrate did not reset start bitrate.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002561}
2562
perkjfa10b552016-10-02 23:45:26 -07002563TEST_F(WebRtcVideoChannel2Test, SetMaxSendBandwidthAndAddSendStream) {
2564 send_parameters_.max_bandwidth_bps = 99999;
2565 FakeVideoSendStream* stream = AddSendStream();
2566 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
2567 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
2568 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2569 ASSERT_EQ(1u, stream->GetVideoStreams().size());
2570 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
2571 stream->GetVideoStreams()[0].max_bitrate_bps);
2572
2573 send_parameters_.max_bandwidth_bps = 77777;
2574 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
2575 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
2576 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2577 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
2578 stream->GetVideoStreams()[0].max_bitrate_bps);
2579}
2580
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002581TEST_F(WebRtcVideoChannel2Test, SetMaxSendBitrateCanIncreaseSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002582 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002583 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002584 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002585 channel_->SetSend(true);
2586
2587 FakeVideoSendStream* stream = AddSendStream();
2588
Peter Boström3afc8c42016-01-27 16:45:21 +01002589 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002590 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Peter Boström3afc8c42016-01-27 16:45:21 +01002591 EXPECT_EQ(cricket::CS_RUNNING,
2592 capturer.Start(capturer.GetSupportedFormats()->front()));
2593
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002594 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
2595 int initial_max_bitrate_bps = streams[0].max_bitrate_bps;
2596 EXPECT_GT(initial_max_bitrate_bps, 0);
2597
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002598 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
2599 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01002600 // Insert a frame to update the encoder config.
2601 EXPECT_TRUE(capturer.CaptureFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002602 streams = stream->GetVideoStreams();
2603 EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps);
deadbeef5a4a75a2016-06-02 16:23:38 -07002604 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002605}
2606
2607TEST_F(WebRtcVideoChannel2Test,
2608 SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002609 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002610 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002611 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002612 channel_->SetSend(true);
2613
2614 FakeVideoSendStream* stream = AddSendStream(
2615 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
2616
2617 // Send a frame to make sure this scales up to >1 stream (simulcast).
2618 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002619 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], true, nullptr, &capturer));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002620 EXPECT_EQ(cricket::CS_RUNNING,
2621 capturer.Start(capturer.GetSupportedFormats()->front()));
2622 EXPECT_TRUE(capturer.CaptureFrame());
2623
2624 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
2625 ASSERT_GT(streams.size(), 1u)
2626 << "Without simulcast this test doesn't make sense.";
pbosbe16f792015-10-16 12:49:39 -07002627 int initial_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002628 EXPECT_GT(initial_max_bitrate_bps, 0);
2629
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002630 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
2631 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01002632 // Insert a frame to update the encoder config.
2633 EXPECT_TRUE(capturer.CaptureFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002634 streams = stream->GetVideoStreams();
pbosbe16f792015-10-16 12:49:39 -07002635 int increased_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002636 EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps);
2637
deadbeef5a4a75a2016-06-02 16:23:38 -07002638 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], true, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002639}
2640
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002641TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMaxQuantization) {
2642 static const char* kMaxQuantization = "21";
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002643 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002644 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002645 parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
2646 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00002647 EXPECT_EQ(static_cast<unsigned int>(atoi(kMaxQuantization)),
2648 AddSendStream()->GetVideoStreams().back().max_qp);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002649
2650 VideoCodec codec;
2651 EXPECT_TRUE(channel_->GetSendCodec(&codec));
2652 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
2653}
2654
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002655TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) {
2656 // TODO(pbos): Should we only allow the dynamic range?
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002657 static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002658 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002659 parameters.codecs.push_back(GetEngineCodec("VP8"));
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002660 for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002661 parameters.codecs[0].id = kIncorrectPayloads[i];
2662 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pkasting@chromium.orgd3245462015-02-23 21:28:22 +00002663 << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002664 }
2665}
2666
2667TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptAllValidPayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002668 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002669 parameters.codecs.push_back(GetEngineCodec("VP8"));
magjedf823ede2016-11-12 09:53:04 -08002670 for (int payload_type = 96; payload_type <= 127; ++payload_type) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002671 parameters.codecs[0].id = payload_type;
2672 EXPECT_TRUE(channel_->SetSendParameters(parameters))
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002673 << "Payload type '" << payload_type << "' rejected.";
2674 }
2675}
2676
deadbeef67cf2c12016-04-13 10:07:16 -07002677// Test that setting the a different set of codecs but with an identical front
2678// codec doesn't result in the stream being recreated.
2679// This may happen when a subsequent negotiation includes fewer codecs, as a
2680// result of one of the codecs being rejected.
2681TEST_F(WebRtcVideoChannel2Test,
2682 SetSendCodecsIdenticalFirstCodecDoesntRecreateStream) {
2683 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08002684 parameters1.codecs.push_back(GetEngineCodec("VP8"));
2685 parameters1.codecs.push_back(GetEngineCodec("VP9"));
deadbeef67cf2c12016-04-13 10:07:16 -07002686 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
2687
2688 AddSendStream();
2689 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2690
2691 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08002692 parameters2.codecs.push_back(GetEngineCodec("VP8"));
deadbeef67cf2c12016-04-13 10:07:16 -07002693 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
2694 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2695}
2696
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002697TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithOnlyVp8) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002698 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002699 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002700 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002701}
2702
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002703// Test that we set our inbound RTX codecs properly.
2704TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithRtx) {
magjed509e4fe2016-11-18 01:34:11 -08002705 const int kUnusedPayloadType1 = 126;
2706 const int kUnusedPayloadType2 = 127;
2707 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
2708 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
2709
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002710 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002711 parameters.codecs.push_back(GetEngineCodec("VP8"));
2712 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002713 parameters.codecs.push_back(rtx_codec);
2714 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002715 << "RTX codec without associated payload should be rejected.";
2716
magjed509e4fe2016-11-18 01:34:11 -08002717 parameters.codecs[1].SetParam("apt", kUnusedPayloadType2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002718 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002719 << "RTX codec with invalid associated payload type should be rejected.";
2720
magjed509e4fe2016-11-18 01:34:11 -08002721 parameters.codecs[1].SetParam("apt", GetEngineCodec("VP8").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002722 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002723
magjed509e4fe2016-11-18 01:34:11 -08002724 cricket::VideoCodec rtx_codec2(kUnusedPayloadType2, "rtx");
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002725 rtx_codec2.SetParam("apt", rtx_codec.id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002726 parameters.codecs.push_back(rtx_codec2);
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002727
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002728 EXPECT_FALSE(channel_->SetRecvParameters(parameters)) <<
2729 "RTX codec with another RTX as associated payload type should be "
2730 "rejected.";
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002731}
2732
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002733TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentPayloadType) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002734 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002735 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002736 parameters.codecs[0].id = 99;
2737 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002738}
2739
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00002740TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsAcceptDefaultCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002741 cricket::VideoRecvParameters parameters;
2742 parameters.codecs = engine_.codecs();
2743 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00002744
2745 FakeVideoReceiveStream* stream = AddRecvStream();
Tommi733b5472016-06-10 17:58:01 +02002746 const webrtc::VideoReceiveStream::Config& config = stream->GetConfig();
pbos@webrtc.org776e6f22014-10-29 15:28:39 +00002747 EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].payload_name);
2748 EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002749}
2750
2751TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002752 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002753 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj26752742016-10-24 01:21:16 -07002754 parameters.codecs.push_back(VideoCodec(101, "WTF3"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002755 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002756}
2757
2758// TODO(pbos): Enable VP9 through external codec support
2759TEST_F(WebRtcVideoChannel2Test,
2760 DISABLED_SetRecvCodecsAcceptsMultipleVideoCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002761 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002762 parameters.codecs.push_back(GetEngineCodec("VP8"));
2763 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002764 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002765}
2766
2767TEST_F(WebRtcVideoChannel2Test,
2768 DISABLED_SetRecvCodecsSetsFecForAllVideoCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002769 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002770 parameters.codecs.push_back(GetEngineCodec("VP8"));
2771 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002772 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002773 FAIL(); // TODO(pbos): Verify that the FEC parameters are set for all codecs.
2774}
2775
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002776TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002777 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08002778 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
2779 send_parameters.codecs.push_back(GetEngineCodec("red"));
2780 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002781 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002782
2783 FakeVideoReceiveStream* stream = AddRecvStream();
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002784
magjed509e4fe2016-11-18 01:34:11 -08002785 EXPECT_EQ(GetEngineCodec("ulpfec").id,
brandtrb5f2c3f2016-10-04 23:28:39 -07002786 stream->GetConfig().rtp.ulpfec.ulpfec_payload_type);
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002787
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002788 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08002789 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002790 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002791 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08002792 ASSERT_TRUE(stream != nullptr);
brandtrb5f2c3f2016-10-04 23:28:39 -07002793 EXPECT_EQ(-1, stream->GetConfig().rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08002794 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
2795}
2796
2797// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2798// by default.
2799TEST_F(WebRtcVideoChannel2FlexfecTest, SetRecvParamsWithoutFecDisablesFec) {
2800 cricket::VideoSendParameters send_parameters;
2801 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
2802 send_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2803 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
2804
2805 AddRecvStream(
2806 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2807 const std::list<FakeFlexfecReceiveStream>& streams =
2808 fake_call_->GetFlexfecReceiveStreams();
2809
2810 ASSERT_EQ(1U, streams.size());
2811 const FakeFlexfecReceiveStream& stream = streams.front();
2812 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
2813 stream.GetConfig().flexfec_payload_type);
2814 EXPECT_EQ(kFlexfecSsrc, stream.GetConfig().flexfec_ssrc);
2815 ASSERT_EQ(1U, stream.GetConfig().protected_media_ssrcs.size());
2816 EXPECT_EQ(kSsrcs1[0], stream.GetConfig().protected_media_ssrcs[0]);
2817
2818 cricket::VideoRecvParameters recv_parameters;
2819 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
2820 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
2821 EXPECT_TRUE(streams.empty())
2822 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002823}
2824
brandtre6f98c72016-11-11 03:28:30 -08002825TEST_F(WebRtcVideoChannel2Test, SetSendParamsWithFecEnablesFec) {
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002826 FakeVideoReceiveStream* stream = AddRecvStream();
magjed509e4fe2016-11-18 01:34:11 -08002827 EXPECT_EQ(GetEngineCodec("ulpfec").id,
brandtrb5f2c3f2016-10-04 23:28:39 -07002828 stream->GetConfig().rtp.ulpfec.ulpfec_payload_type);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002829
2830 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08002831 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
2832 recv_parameters.codecs.push_back(GetEngineCodec("red"));
2833 recv_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002834 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
2835 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08002836 ASSERT_TRUE(stream != nullptr);
magjed509e4fe2016-11-18 01:34:11 -08002837 EXPECT_EQ(GetEngineCodec("ulpfec").id,
2838 stream->GetConfig().rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08002839 << "ULPFEC should be enabled on the receive stream.";
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002840
2841 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08002842 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
2843 send_parameters.codecs.push_back(GetEngineCodec("red"));
2844 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002845 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
2846 stream = fake_call_->GetVideoReceiveStreams()[0];
magjed509e4fe2016-11-18 01:34:11 -08002847 EXPECT_EQ(GetEngineCodec("ulpfec").id,
2848 stream->GetConfig().rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08002849 << "ULPFEC should be enabled on the receive stream.";
2850}
2851
2852// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2853// by default.
2854TEST_F(WebRtcVideoChannel2FlexfecTest, SetSendParamsWithFecEnablesFec) {
2855 AddRecvStream(
2856 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2857 const std::list<FakeFlexfecReceiveStream>& streams =
2858 fake_call_->GetFlexfecReceiveStreams();
2859
2860 cricket::VideoRecvParameters recv_parameters;
2861 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
2862 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2863 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
2864 ASSERT_EQ(1U, streams.size());
2865 const FakeFlexfecReceiveStream& stream_with_recv_params = streams.front();
2866 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
2867 stream_with_recv_params.GetConfig().flexfec_payload_type);
2868 EXPECT_EQ(kFlexfecSsrc, stream_with_recv_params.GetConfig().flexfec_ssrc);
2869 EXPECT_EQ(1U,
2870 stream_with_recv_params.GetConfig().protected_media_ssrcs.size());
2871 EXPECT_EQ(kSsrcs1[0],
2872 stream_with_recv_params.GetConfig().protected_media_ssrcs[0]);
2873
2874 cricket::VideoSendParameters send_parameters;
2875 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
2876 send_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2877 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
2878 ASSERT_EQ(1U, streams.size());
2879 const FakeFlexfecReceiveStream& stream_with_send_params = streams.front();
2880 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
2881 stream_with_send_params.GetConfig().flexfec_payload_type);
2882 EXPECT_EQ(kFlexfecSsrc, stream_with_send_params.GetConfig().flexfec_ssrc);
2883 EXPECT_EQ(1U,
2884 stream_with_send_params.GetConfig().protected_media_ssrcs.size());
2885 EXPECT_EQ(kSsrcs1[0],
2886 stream_with_send_params.GetConfig().protected_media_ssrcs[0]);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002887}
2888
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002889TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectDuplicateFecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002890 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002891 parameters.codecs.push_back(GetEngineCodec("VP8"));
2892 parameters.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002893 parameters.codecs[1].id = parameters.codecs[0].id;
2894 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002895}
2896
brandtr468da7c2016-11-22 02:16:47 -08002897// TODO(brandtr): Merge into "non-field trial" test when FlexFEC is enabled
2898// by default.
2899TEST_F(WebRtcVideoChannel2FlexfecTest,
2900 SetSendCodecsRejectDuplicateFecPayloads) {
2901 cricket::VideoRecvParameters parameters;
2902 parameters.codecs.push_back(GetEngineCodec("VP8"));
2903 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2904 parameters.codecs[1].id = parameters.codecs[0].id;
2905 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
2906}
2907
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002908TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectDuplicateCodecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002909 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002910 parameters.codecs.push_back(GetEngineCodec("VP8"));
2911 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002912 parameters.codecs[1].id = parameters.codecs[0].id;
2913 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002914}
2915
2916TEST_F(WebRtcVideoChannel2Test,
2917 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002918 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002919 parameters.codecs.push_back(GetEngineCodec("VP8"));
2920 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002921 parameters.codecs[1].id += 1;
2922 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002923}
2924
deadbeef67cf2c12016-04-13 10:07:16 -07002925// Test that setting the same codecs but with a different order
deadbeef874ca3a2015-08-20 17:19:20 -07002926// doesn't result in the stream being recreated.
2927TEST_F(WebRtcVideoChannel2Test,
deadbeef67cf2c12016-04-13 10:07:16 -07002928 SetRecvCodecsDifferentOrderDoesntRecreateStream) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002929 cricket::VideoRecvParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08002930 parameters1.codecs.push_back(GetEngineCodec("VP8"));
2931 parameters1.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002932 EXPECT_TRUE(channel_->SetRecvParameters(parameters1));
deadbeef874ca3a2015-08-20 17:19:20 -07002933
2934 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2935 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2936
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002937 cricket::VideoRecvParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08002938 parameters2.codecs.push_back(GetEngineCodec("red"));
2939 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002940 EXPECT_TRUE(channel_->SetRecvParameters(parameters2));
deadbeef874ca3a2015-08-20 17:19:20 -07002941 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2942}
2943
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002944TEST_F(WebRtcVideoChannel2Test, SendStreamNotSendingByDefault) {
2945 EXPECT_FALSE(AddSendStream()->IsSending());
2946}
2947
pbos@webrtc.org85f42942014-07-22 09:14:58 +00002948TEST_F(WebRtcVideoChannel2Test, ReceiveStreamReceivingByDefault) {
2949 EXPECT_TRUE(AddRecvStream()->IsReceiving());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002950}
2951
2952TEST_F(WebRtcVideoChannel2Test, SetSend) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +00002953 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002954 EXPECT_FALSE(stream->IsSending());
2955
2956 // false->true
2957 EXPECT_TRUE(channel_->SetSend(true));
2958 EXPECT_TRUE(stream->IsSending());
2959 // true->true
2960 EXPECT_TRUE(channel_->SetSend(true));
2961 EXPECT_TRUE(stream->IsSending());
2962 // true->false
2963 EXPECT_TRUE(channel_->SetSend(false));
2964 EXPECT_FALSE(stream->IsSending());
2965 // false->false
2966 EXPECT_TRUE(channel_->SetSend(false));
2967 EXPECT_FALSE(stream->IsSending());
2968
2969 EXPECT_TRUE(channel_->SetSend(true));
2970 FakeVideoSendStream* new_stream = AddSendStream();
2971 EXPECT_TRUE(new_stream->IsSending())
2972 << "Send stream created after SetSend(true) not sending initially.";
2973}
2974
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00002975// This test verifies DSCP settings are properly applied on video media channel.
2976TEST_F(WebRtcVideoChannel2Test, TestSetDscpOptions) {
kwiberg686a8ef2016-02-26 03:00:35 -08002977 std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00002978 new cricket::FakeNetworkInterface);
nisse51542be2016-02-12 02:27:06 -08002979 MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002980 std::unique_ptr<VideoMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002981
2982 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
2983 channel->SetInterface(network_interface.get());
2984 // Default value when DSCP is disabled should be DSCP_DEFAULT.
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00002985 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
nisse51542be2016-02-12 02:27:06 -08002986
2987 config.enable_dscp = true;
2988 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
2989 channel->SetInterface(network_interface.get());
2990 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
2991
2992 // Verify that setting the option to false resets the
2993 // DiffServCodePoint.
2994 config.enable_dscp = false;
2995 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
2996 channel->SetInterface(network_interface.get());
2997 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002998}
2999
deadbeef13871492015-12-09 12:37:51 -08003000// This test verifies that the RTCP reduced size mode is properly applied to
3001// send video streams.
3002TEST_F(WebRtcVideoChannel2Test, TestSetSendRtcpReducedSize) {
3003 // Create stream, expecting that default mode is "compound".
3004 FakeVideoSendStream* stream1 = AddSendStream();
3005 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
3006
3007 // Now enable reduced size mode.
3008 send_parameters_.rtcp.reduced_size = true;
3009 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3010 stream1 = fake_call_->GetVideoSendStreams()[0];
3011 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
3012
3013 // Create a new stream and ensure it picks up the reduced size mode.
3014 FakeVideoSendStream* stream2 = AddSendStream();
3015 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
3016}
3017
3018// This test verifies that the RTCP reduced size mode is properly applied to
3019// receive video streams.
3020TEST_F(WebRtcVideoChannel2Test, TestSetRecvRtcpReducedSize) {
3021 // Create stream, expecting that default mode is "compound".
3022 FakeVideoReceiveStream* stream1 = AddRecvStream();
3023 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
3024
3025 // Now enable reduced size mode.
Taylor Brandstetter5f0b83b2016-03-18 15:02:07 -07003026 // TODO(deadbeef): Once "recv_parameters" becomes "receiver_parameters",
3027 // the reduced_size flag should come from that.
3028 send_parameters_.rtcp.reduced_size = true;
3029 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
deadbeef13871492015-12-09 12:37:51 -08003030 stream1 = fake_call_->GetVideoReceiveStreams()[0];
3031 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
3032
3033 // Create a new stream and ensure it picks up the reduced size mode.
3034 FakeVideoReceiveStream* stream2 = AddRecvStream();
3035 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
3036}
3037
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003038TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) {
skvlad7a43d252016-03-22 15:32:27 -07003039 EXPECT_EQ(webrtc::kNetworkUp,
3040 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
3041 EXPECT_EQ(webrtc::kNetworkUp,
3042 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003043
3044 channel_->OnReadyToSend(false);
skvlad7a43d252016-03-22 15:32:27 -07003045 EXPECT_EQ(webrtc::kNetworkDown,
3046 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
3047 EXPECT_EQ(webrtc::kNetworkUp,
3048 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003049
3050 channel_->OnReadyToSend(true);
skvlad7a43d252016-03-22 15:32:27 -07003051 EXPECT_EQ(webrtc::kNetworkUp,
3052 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
3053 EXPECT_EQ(webrtc::kNetworkUp,
3054 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003055}
3056
Peter Boström74d9ed72015-03-26 16:28:31 +01003057TEST_F(WebRtcVideoChannel2Test, GetStatsReportsSentCodecName) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003058 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003059 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003060 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström74d9ed72015-03-26 16:28:31 +01003061
3062 AddSendStream();
3063
3064 cricket::VideoMediaInfo info;
3065 ASSERT_TRUE(channel_->GetStats(&info));
magjed509e4fe2016-11-18 01:34:11 -08003066 EXPECT_EQ("VP8", info.senders[0].codec_name);
Peter Boström74d9ed72015-03-26 16:28:31 +01003067}
3068
Peter Boströmb7d9a972015-12-18 16:01:11 +01003069TEST_F(WebRtcVideoChannel2Test, GetStatsReportsEncoderImplementationName) {
3070 FakeVideoSendStream* stream = AddSendStream();
3071 webrtc::VideoSendStream::Stats stats;
3072 stats.encoder_implementation_name = "encoder_implementation_name";
3073 stream->SetStats(stats);
3074
3075 cricket::VideoMediaInfo info;
3076 ASSERT_TRUE(channel_->GetStats(&info));
3077 EXPECT_EQ(stats.encoder_implementation_name,
3078 info.senders[0].encoder_implementation_name);
3079}
3080
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00003081TEST_F(WebRtcVideoChannel2Test, GetStatsReportsCpuOveruseMetrics) {
3082 FakeVideoSendStream* stream = AddSendStream();
3083 webrtc::VideoSendStream::Stats stats;
3084 stats.avg_encode_time_ms = 13;
3085 stats.encode_usage_percent = 42;
3086 stream->SetStats(stats);
3087
3088 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003089 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00003090 EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
3091 EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
3092}
3093
sakal43536c32016-10-24 01:46:43 -07003094TEST_F(WebRtcVideoChannel2Test, GetStatsReportsFramesEncoded) {
3095 FakeVideoSendStream* stream = AddSendStream();
3096 webrtc::VideoSendStream::Stats stats;
3097 stats.frames_encoded = 13;
3098 stream->SetStats(stats);
3099
3100 cricket::VideoMediaInfo info;
3101 ASSERT_TRUE(channel_->GetStats(&info));
3102 EXPECT_EQ(stats.frames_encoded, info.senders[0].frames_encoded);
3103}
3104
sakal87da4042016-10-31 06:53:47 -07003105TEST_F(WebRtcVideoChannel2Test, GetStatsReportsQpSum) {
3106 FakeVideoSendStream* stream = AddSendStream();
3107 webrtc::VideoSendStream::Stats stats;
3108 stats.qp_sum = rtc::Optional<uint64_t>(13);
3109 stream->SetStats(stats);
3110
3111 cricket::VideoMediaInfo info;
3112 ASSERT_TRUE(channel_->GetStats(&info));
3113 EXPECT_EQ(stats.qp_sum, info.senders[0].qp_sum);
3114}
3115
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003116TEST_F(WebRtcVideoChannel2Test, GetStatsReportsUpperResolution) {
3117 FakeVideoSendStream* stream = AddSendStream();
3118 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003119 stats.substreams[17].width = 123;
3120 stats.substreams[17].height = 40;
3121 stats.substreams[42].width = 80;
3122 stats.substreams[42].height = 31;
3123 stats.substreams[11].width = 20;
3124 stats.substreams[11].height = 90;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003125 stream->SetStats(stats);
3126
3127 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003128 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003129 ASSERT_EQ(1u, info.senders.size());
3130 EXPECT_EQ(123, info.senders[0].send_frame_width);
3131 EXPECT_EQ(90, info.senders[0].send_frame_height);
3132}
3133
Pera48ddb72016-09-29 11:48:50 +02003134TEST_F(WebRtcVideoChannel2Test, GetStatsReportsPreferredBitrate) {
3135 FakeVideoSendStream* stream = AddSendStream();
3136 webrtc::VideoSendStream::Stats stats;
3137 stats.preferred_media_bitrate_bps = 5;
3138 stream->SetStats(stats);
3139
3140 cricket::VideoMediaInfo info;
3141 ASSERT_TRUE(channel_->GetStats(&info));
3142 ASSERT_EQ(1u, info.senders.size());
3143 EXPECT_EQ(5, info.senders[0].preferred_bitrate);
3144}
3145
perkj803d97f2016-11-01 11:45:46 -07003146TEST_F(WebRtcVideoChannel2Test, GetStatsReportsCpuAdaptationStats) {
3147 FakeVideoSendStream* stream = AddSendStream();
3148 webrtc::VideoSendStream::Stats stats;
3149 stats.number_of_cpu_adapt_changes = 2;
3150 stats.cpu_limited_resolution = true;
3151 stream->SetStats(stats);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003152
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003153 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003154 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003155 ASSERT_EQ(1U, info.senders.size());
Per766ad3b2016-04-05 15:23:49 +02003156 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_CPU, info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07003157 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003158}
3159
perkj803d97f2016-11-01 11:45:46 -07003160TEST_F(WebRtcVideoChannel2Test, GetStatsReportsAdaptationAndBandwidthStats) {
3161 FakeVideoSendStream* stream = AddSendStream();
asapersson17821db2015-12-14 02:08:12 -08003162 webrtc::VideoSendStream::Stats stats;
perkj803d97f2016-11-01 11:45:46 -07003163 stats.number_of_cpu_adapt_changes = 2;
3164 stats.cpu_limited_resolution = true;
asapersson17821db2015-12-14 02:08:12 -08003165 stats.bw_limited_resolution = true;
perkj803d97f2016-11-01 11:45:46 -07003166 stream->SetStats(stats);
3167
3168 cricket::VideoMediaInfo info;
asapersson17821db2015-12-14 02:08:12 -08003169 EXPECT_TRUE(channel_->GetStats(&info));
3170 ASSERT_EQ(1U, info.senders.size());
Per766ad3b2016-04-05 15:23:49 +02003171 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_CPU |
3172 WebRtcVideoChannel2::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08003173 info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07003174 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
asapersson17821db2015-12-14 02:08:12 -08003175}
3176
3177TEST_F(WebRtcVideoChannel2Test,
3178 GetStatsTranslatesBandwidthLimitedResolutionCorrectly) {
3179 FakeVideoSendStream* stream = AddSendStream();
3180 webrtc::VideoSendStream::Stats stats;
3181 stats.bw_limited_resolution = true;
3182 stream->SetStats(stats);
3183
3184 cricket::VideoMediaInfo info;
3185 EXPECT_TRUE(channel_->GetStats(&info));
3186 ASSERT_EQ(1U, info.senders.size());
Per766ad3b2016-04-05 15:23:49 +02003187 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08003188 info.senders[0].adapt_reason);
3189}
3190
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003191TEST_F(WebRtcVideoChannel2Test,
3192 GetStatsTranslatesSendRtcpPacketTypesCorrectly) {
3193 FakeVideoSendStream* stream = AddSendStream();
3194 webrtc::VideoSendStream::Stats stats;
3195 stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2;
3196 stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3;
3197 stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4;
3198
3199 stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5;
3200 stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7;
3201 stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9;
3202
3203 stream->SetStats(stats);
3204
3205 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003206 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003207 EXPECT_EQ(7, info.senders[0].firs_rcvd);
3208 EXPECT_EQ(10, info.senders[0].nacks_rcvd);
3209 EXPECT_EQ(13, info.senders[0].plis_rcvd);
3210}
3211
3212TEST_F(WebRtcVideoChannel2Test,
3213 GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) {
3214 FakeVideoReceiveStream* stream = AddRecvStream();
3215 webrtc::VideoReceiveStream::Stats stats;
3216 stats.rtcp_packet_type_counts.fir_packets = 2;
3217 stats.rtcp_packet_type_counts.nack_packets = 3;
3218 stats.rtcp_packet_type_counts.pli_packets = 4;
3219 stream->SetStats(stats);
3220
3221 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003222 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003223 EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets,
3224 info.receivers[0].firs_sent);
3225 EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets,
3226 info.receivers[0].nacks_sent);
3227 EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets,
3228 info.receivers[0].plis_sent);
3229}
3230
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003231TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesDecodeStatsCorrectly) {
3232 FakeVideoReceiveStream* stream = AddRecvStream();
3233 webrtc::VideoReceiveStream::Stats stats;
Peter Boströmb7d9a972015-12-18 16:01:11 +01003234 stats.decoder_implementation_name = "decoder_implementation_name";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003235 stats.decode_ms = 2;
3236 stats.max_decode_ms = 3;
3237 stats.current_delay_ms = 4;
3238 stats.target_delay_ms = 5;
3239 stats.jitter_buffer_ms = 6;
3240 stats.min_playout_delay_ms = 7;
3241 stats.render_delay_ms = 8;
asapersson26dd92b2016-08-30 00:45:45 -07003242 stats.width = 9;
3243 stats.height = 10;
sakale5ba44e2016-10-26 07:09:24 -07003244 stats.frames_decoded = 11;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003245 stream->SetStats(stats);
3246
3247 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003248 ASSERT_TRUE(channel_->GetStats(&info));
Peter Boströmb7d9a972015-12-18 16:01:11 +01003249 EXPECT_EQ(stats.decoder_implementation_name,
3250 info.receivers[0].decoder_implementation_name);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003251 EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
3252 EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
3253 EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
3254 EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
3255 EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
3256 EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
3257 EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
asapersson26dd92b2016-08-30 00:45:45 -07003258 EXPECT_EQ(stats.width, info.receivers[0].frame_width);
3259 EXPECT_EQ(stats.height, info.receivers[0].frame_height);
sakale5ba44e2016-10-26 07:09:24 -07003260 EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003261}
3262
Peter Boström393347f2015-04-22 14:52:45 +02003263TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesReceivePacketStatsCorrectly) {
3264 FakeVideoReceiveStream* stream = AddRecvStream();
3265 webrtc::VideoReceiveStream::Stats stats;
3266 stats.rtp_stats.transmitted.payload_bytes = 2;
3267 stats.rtp_stats.transmitted.header_bytes = 3;
3268 stats.rtp_stats.transmitted.padding_bytes = 4;
3269 stats.rtp_stats.transmitted.packets = 5;
3270 stats.rtcp_stats.cumulative_lost = 6;
3271 stats.rtcp_stats.fraction_lost = 7;
3272 stream->SetStats(stats);
3273
3274 cricket::VideoMediaInfo info;
3275 ASSERT_TRUE(channel_->GetStats(&info));
3276 EXPECT_EQ(stats.rtp_stats.transmitted.payload_bytes +
3277 stats.rtp_stats.transmitted.header_bytes +
3278 stats.rtp_stats.transmitted.padding_bytes,
3279 info.receivers[0].bytes_rcvd);
3280 EXPECT_EQ(stats.rtp_stats.transmitted.packets,
3281 info.receivers[0].packets_rcvd);
3282 EXPECT_EQ(stats.rtcp_stats.cumulative_lost, info.receivers[0].packets_lost);
3283 EXPECT_EQ(static_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8),
3284 info.receivers[0].fraction_lost);
3285}
3286
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003287TEST_F(WebRtcVideoChannel2Test, TranslatesCallStatsCorrectly) {
3288 AddSendStream();
3289 AddSendStream();
3290 webrtc::Call::Stats stats;
3291 stats.rtt_ms = 123;
3292 fake_call_->SetStats(stats);
3293
3294 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003295 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003296 ASSERT_EQ(2u, info.senders.size());
3297 EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms);
3298 EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
3299}
3300
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003301TEST_F(WebRtcVideoChannel2Test, TranslatesSenderBitrateStatsCorrectly) {
3302 FakeVideoSendStream* stream = AddSendStream();
3303 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003304 stats.target_media_bitrate_bps = 156;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003305 stats.media_bitrate_bps = 123;
3306 stats.substreams[17].total_bitrate_bps = 1;
3307 stats.substreams[17].retransmit_bitrate_bps = 2;
3308 stats.substreams[42].total_bitrate_bps = 3;
3309 stats.substreams[42].retransmit_bitrate_bps = 4;
3310 stream->SetStats(stats);
3311
3312 FakeVideoSendStream* stream2 = AddSendStream();
3313 webrtc::VideoSendStream::Stats stats2;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003314 stats2.target_media_bitrate_bps = 200;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003315 stats2.media_bitrate_bps = 321;
3316 stats2.substreams[13].total_bitrate_bps = 5;
3317 stats2.substreams[13].retransmit_bitrate_bps = 6;
3318 stats2.substreams[21].total_bitrate_bps = 7;
3319 stats2.substreams[21].retransmit_bitrate_bps = 8;
3320 stream2->SetStats(stats2);
3321
3322 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003323 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003324 ASSERT_EQ(2u, info.senders.size());
3325 // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
3326 // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
3327 EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate);
3328 EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate);
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003329 EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
3330 info.bw_estimations[0].target_enc_bitrate);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003331 EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
3332 info.bw_estimations[0].actual_enc_bitrate);
3333 EXPECT_EQ(1 + 3 + 5 + 7, info.bw_estimations[0].transmit_bitrate)
3334 << "Bandwidth stats should take all streams into account.";
3335 EXPECT_EQ(2 + 4 + 6 + 8, info.bw_estimations[0].retransmit_bitrate)
3336 << "Bandwidth stats should take all streams into account.";
3337}
3338
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003339TEST_F(WebRtcVideoChannel2Test, DefaultReceiveStreamReconfiguresToUseRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003340 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003341
Peter Boström0c4e06b2015-10-07 12:23:21 +02003342 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3343 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003344
3345 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
3346 const size_t kDataLength = 12;
3347 uint8_t data[kDataLength];
3348 memset(data, 0, sizeof(data));
3349 rtc::SetBE32(&data[8], ssrcs[0]);
jbaucheec21bd2016-03-20 06:15:43 -07003350 rtc::CopyOnWriteBuffer packet(data, kDataLength);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003351 rtc::PacketTime packet_time;
3352 channel_->OnPacketReceived(&packet, packet_time);
3353
3354 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
3355 << "No default receive stream created.";
3356 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
Peter Boströmd8b01092016-05-12 16:44:36 +02003357 EXPECT_TRUE(recv_stream->GetConfig().rtp.rtx.empty())
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003358 << "Default receive stream should not have configured RTX";
3359
3360 EXPECT_TRUE(channel_->AddRecvStream(
3361 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
3362 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
3363 << "AddRecvStream should've reconfigured, not added a new receiver.";
3364 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
Peter Boströmd8b01092016-05-12 16:44:36 +02003365 EXPECT_FALSE(recv_stream->GetConfig().rtp.rtx.empty());
3366 EXPECT_EQ(recv_stream->GetConfig().decoders.size(),
3367 recv_stream->GetConfig().rtp.rtx.size())
3368 << "RTX should be mapped for all decoders/payload types.";
3369 for (const auto& kv : recv_stream->GetConfig().rtp.rtx) {
3370 EXPECT_EQ(rtx_ssrcs[0], kv.second.ssrc);
3371 }
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003372}
3373
Peter Boströmd4362cd2015-03-25 14:17:23 +01003374TEST_F(WebRtcVideoChannel2Test, RejectsAddingStreamsWithMissingSsrcsForRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003375 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd4362cd2015-03-25 14:17:23 +01003376
Peter Boström0c4e06b2015-10-07 12:23:21 +02003377 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3378 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd4362cd2015-03-25 14:17:23 +01003379
3380 StreamParams sp =
3381 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
3382 sp.ssrcs = ssrcs; // Without RTXs, this is the important part.
3383
3384 EXPECT_FALSE(channel_->AddSendStream(sp));
3385 EXPECT_FALSE(channel_->AddRecvStream(sp));
3386}
3387
Peter Boströmd6f4c252015-03-26 16:23:04 +01003388TEST_F(WebRtcVideoChannel2Test, RejectsAddingStreamsWithOverlappingRtxSsrcs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003389 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003390
Peter Boström0c4e06b2015-10-07 12:23:21 +02003391 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3392 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd6f4c252015-03-26 16:23:04 +01003393
3394 StreamParams sp =
3395 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
3396
3397 EXPECT_TRUE(channel_->AddSendStream(sp));
3398 EXPECT_TRUE(channel_->AddRecvStream(sp));
3399
3400 // The RTX SSRC is already used in previous streams, using it should fail.
3401 sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]);
3402 EXPECT_FALSE(channel_->AddSendStream(sp));
3403 EXPECT_FALSE(channel_->AddRecvStream(sp));
3404
3405 // After removing the original stream this should be fine to add (makes sure
3406 // that RTX ssrcs are not forever taken).
3407 EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0]));
3408 EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0]));
3409 EXPECT_TRUE(channel_->AddSendStream(sp));
3410 EXPECT_TRUE(channel_->AddRecvStream(sp));
3411}
3412
3413TEST_F(WebRtcVideoChannel2Test,
3414 RejectsAddingStreamsWithOverlappingSimulcastSsrcs) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003415 static const uint32_t kFirstStreamSsrcs[] = {1, 2, 3};
3416 static const uint32_t kOverlappingStreamSsrcs[] = {4, 3, 5};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003417 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003418
Peter Boströmd6f4c252015-03-26 16:23:04 +01003419 StreamParams sp =
3420 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs));
3421
3422 EXPECT_TRUE(channel_->AddSendStream(sp));
3423 EXPECT_TRUE(channel_->AddRecvStream(sp));
3424
3425 // One of the SSRCs is already used in previous streams, using it should fail.
3426 sp = cricket::CreateSimStreamParams("cname",
3427 MAKE_VECTOR(kOverlappingStreamSsrcs));
3428 EXPECT_FALSE(channel_->AddSendStream(sp));
3429 EXPECT_FALSE(channel_->AddRecvStream(sp));
3430
3431 // After removing the original stream this should be fine to add (makes sure
3432 // that RTX ssrcs are not forever taken).
Peter Boström3548dd22015-05-22 18:48:36 +02003433 EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0]));
3434 EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0]));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003435 EXPECT_TRUE(channel_->AddSendStream(sp));
3436 EXPECT_TRUE(channel_->AddRecvStream(sp));
3437}
3438
Peter Boström259bd202015-05-28 13:39:50 +02003439TEST_F(WebRtcVideoChannel2Test, ReportsSsrcGroupsInStats) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003440 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström259bd202015-05-28 13:39:50 +02003441
3442 static const uint32_t kSenderSsrcs[] = {4, 7, 10};
3443 static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11};
3444
3445 StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams(
3446 "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs));
3447
3448 EXPECT_TRUE(channel_->AddSendStream(sender_sp));
3449
3450 static const uint32_t kReceiverSsrcs[] = {3};
3451 static const uint32_t kReceiverRtxSsrcs[] = {2};
3452
3453 StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams(
3454 "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs));
3455 EXPECT_TRUE(channel_->AddRecvStream(receiver_sp));
3456
3457 cricket::VideoMediaInfo info;
3458 ASSERT_TRUE(channel_->GetStats(&info));
3459
3460 ASSERT_EQ(1u, info.senders.size());
3461 ASSERT_EQ(1u, info.receivers.size());
3462
3463 EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups);
3464 EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups);
3465 EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
3466}
3467
pbosf42376c2015-08-28 07:35:32 -07003468TEST_F(WebRtcVideoChannel2Test, MapsReceivedPayloadTypeToCodecName) {
3469 FakeVideoReceiveStream* stream = AddRecvStream();
3470 webrtc::VideoReceiveStream::Stats stats;
3471 cricket::VideoMediaInfo info;
3472
3473 // Report no codec name before receiving.
3474 stream->SetStats(stats);
3475 ASSERT_TRUE(channel_->GetStats(&info));
3476 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
3477
3478 // Report VP8 if we're receiving it.
magjed509e4fe2016-11-18 01:34:11 -08003479 stats.current_payload_type = GetEngineCodec("VP8").id;
pbosf42376c2015-08-28 07:35:32 -07003480 stream->SetStats(stats);
3481 ASSERT_TRUE(channel_->GetStats(&info));
3482 EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());
3483
3484 // Report no codec name for unknown playload types.
3485 stats.current_payload_type = 3;
3486 stream->SetStats(stats);
3487 ASSERT_TRUE(channel_->GetStats(&info));
3488 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
3489}
3490
magjed509e4fe2016-11-18 01:34:11 -08003491void WebRtcVideoChannel2Test::TestReceiveUnsignaledSsrcPacket(
noahricd10a68e2015-07-10 11:27:55 -07003492 uint8_t payload_type,
3493 bool expect_created_receive_stream) {
magjed509e4fe2016-11-18 01:34:11 -08003494 // kRedRtxPayloadType must currently be unused.
3495 EXPECT_FALSE(FindCodecById(engine_.codecs(), kRedRtxPayloadType));
3496
noahricd10a68e2015-07-10 11:27:55 -07003497 // Add a RED RTX codec.
3498 VideoCodec red_rtx_codec =
magjed509e4fe2016-11-18 01:34:11 -08003499 VideoCodec::CreateRtxCodec(kRedRtxPayloadType, GetEngineCodec("red").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003500 recv_parameters_.codecs.push_back(red_rtx_codec);
3501 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
noahricd10a68e2015-07-10 11:27:55 -07003502
3503 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
3504 const size_t kDataLength = 12;
3505 uint8_t data[kDataLength];
3506 memset(data, 0, sizeof(data));
3507
3508 rtc::Set8(data, 1, payload_type);
3509 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
jbaucheec21bd2016-03-20 06:15:43 -07003510 rtc::CopyOnWriteBuffer packet(data, kDataLength);
noahricd10a68e2015-07-10 11:27:55 -07003511 rtc::PacketTime packet_time;
3512 channel_->OnPacketReceived(&packet, packet_time);
3513
3514 if (expect_created_receive_stream) {
3515 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
3516 << "Should have created a receive stream for payload type: "
3517 << payload_type;
3518 } else {
3519 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size())
3520 << "Shouldn't have created a receive stream for payload type: "
3521 << payload_type;
3522 }
3523}
3524
3525TEST_F(WebRtcVideoChannel2Test, Vp8PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003526 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
3527 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003528}
3529
3530TEST_F(WebRtcVideoChannel2Test, Vp9PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003531 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP9").id,
3532 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003533}
3534
3535TEST_F(WebRtcVideoChannel2Test, RtxPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003536 const cricket::VideoCodec vp8 = GetEngineCodec("VP8");
3537 const int rtx_vp8_payload_type = default_apt_rtx_types_[vp8.id];
3538 TestReceiveUnsignaledSsrcPacket(rtx_vp8_payload_type,
3539 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003540}
3541
3542TEST_F(WebRtcVideoChannel2Test, UlpfecPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003543 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("ulpfec").id,
3544 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003545}
3546
brandtr468da7c2016-11-22 02:16:47 -08003547// TODO(brandtr): Change to "non-field trial" test when FlexFEC is enabled
3548// by default.
3549TEST_F(WebRtcVideoChannel2FlexfecTest,
3550 FlexfecPacketDoesntCreateUnsignalledStream) {
3551 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("flexfec-03").id,
3552 false /* expect_created_receive_stream */);
3553}
3554
noahricd10a68e2015-07-10 11:27:55 -07003555TEST_F(WebRtcVideoChannel2Test, RedRtxPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08003556 TestReceiveUnsignaledSsrcPacket(kRedRtxPayloadType,
3557 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07003558}
3559
skvladdc1c62c2016-03-16 19:07:43 -07003560TEST_F(WebRtcVideoChannel2Test, CanSentMaxBitrateForExistingStream) {
3561 AddSendStream();
3562
3563 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07003564 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
skvladdc1c62c2016-03-16 19:07:43 -07003565 cricket::VideoFormat capture_format_hd =
3566 capturer.GetSupportedFormats()->front();
3567 EXPECT_EQ(1280, capture_format_hd.width);
3568 EXPECT_EQ(720, capture_format_hd.height);
3569 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
3570 EXPECT_TRUE(channel_->SetSend(true));
perkjfa10b552016-10-02 23:45:26 -07003571 capturer.CaptureFrame();
skvladdc1c62c2016-03-16 19:07:43 -07003572
perkjfa10b552016-10-02 23:45:26 -07003573 int default_encoder_bitrate = GetMaxEncoderBitrate();
brandtr468da7c2016-11-22 02:16:47 -08003574 EXPECT_GT(default_encoder_bitrate, 1000);
skvladdc1c62c2016-03-16 19:07:43 -07003575
3576 // TODO(skvlad): Resolve the inconsistency between the interpretation
3577 // of the global bitrate limit for audio and video:
3578 // - Audio: max_bandwidth_bps = 0 - fail the operation,
3579 // max_bandwidth_bps = -1 - remove the bandwidth limit
3580 // - Video: max_bandwidth_bps = 0 - remove the bandwidth limit,
3581 // max_bandwidth_bps = -1 - do not change the previously set
3582 // limit.
3583
perkjfa10b552016-10-02 23:45:26 -07003584 SetAndExpectMaxBitrate(1000, 0, 1000);
3585 SetAndExpectMaxBitrate(1000, 800, 800);
3586 SetAndExpectMaxBitrate(600, 800, 600);
3587 SetAndExpectMaxBitrate(0, 800, 800);
3588 SetAndExpectMaxBitrate(0, 0, default_encoder_bitrate);
skvladdc1c62c2016-03-16 19:07:43 -07003589
deadbeef5a4a75a2016-06-02 16:23:38 -07003590 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
skvladdc1c62c2016-03-16 19:07:43 -07003591}
3592
3593TEST_F(WebRtcVideoChannel2Test, CannotSetMaxBitrateForNonexistentStream) {
3594 webrtc::RtpParameters nonexistent_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003595 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07003596 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
3597
3598 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003599 EXPECT_FALSE(
3600 channel_->SetRtpSendParameters(last_ssrc_, nonexistent_parameters));
skvladdc1c62c2016-03-16 19:07:43 -07003601}
3602
3603TEST_F(WebRtcVideoChannel2Test,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003604 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvladdc1c62c2016-03-16 19:07:43 -07003605 // This test verifies that setting RtpParameters succeeds only if
3606 // the structure contains exactly one encoding.
deadbeefdbe2b872016-03-22 15:42:00 -07003607 // TODO(skvlad): Update this test when we start supporting setting parameters
skvladdc1c62c2016-03-16 19:07:43 -07003608 // for each encoding individually.
3609
3610 AddSendStream();
3611 // Setting RtpParameters with no encoding is expected to fail.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003612 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
3613 parameters.encodings.clear();
3614 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07003615 // Setting RtpParameters with exactly one encoding should succeed.
3616 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003617 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07003618 // Two or more encodings should result in failure.
3619 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003620 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07003621}
3622
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07003623// Test that a stream will not be sending if its encoding is made inactive
3624// through SetRtpSendParameters.
deadbeefdbe2b872016-03-22 15:42:00 -07003625// TODO(deadbeef): Update this test when we start supporting setting parameters
3626// for each encoding individually.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003627TEST_F(WebRtcVideoChannel2Test, SetRtpSendParametersEncodingsActive) {
deadbeefdbe2b872016-03-22 15:42:00 -07003628 FakeVideoSendStream* stream = AddSendStream();
3629 EXPECT_TRUE(channel_->SetSend(true));
3630 EXPECT_TRUE(stream->IsSending());
3631
3632 // Get current parameters and change "active" to false.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003633 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
deadbeefdbe2b872016-03-22 15:42:00 -07003634 ASSERT_EQ(1u, parameters.encodings.size());
3635 ASSERT_TRUE(parameters.encodings[0].active);
3636 parameters.encodings[0].active = false;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003637 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
deadbeefdbe2b872016-03-22 15:42:00 -07003638 EXPECT_FALSE(stream->IsSending());
3639
3640 // Now change it back to active and verify we resume sending.
3641 parameters.encodings[0].active = true;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003642 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
deadbeefdbe2b872016-03-22 15:42:00 -07003643 EXPECT_TRUE(stream->IsSending());
3644}
3645
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07003646// Test that if a stream is reconfigured (due to a codec change or other
3647// change) while its encoding is still inactive, it doesn't start sending.
3648TEST_F(WebRtcVideoChannel2Test,
3649 InactiveStreamDoesntStartSendingWhenReconfigured) {
3650 // Set an initial codec list, which will be modified later.
3651 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08003652 parameters1.codecs.push_back(GetEngineCodec("VP8"));
3653 parameters1.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07003654 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
3655
3656 FakeVideoSendStream* stream = AddSendStream();
3657 EXPECT_TRUE(channel_->SetSend(true));
3658 EXPECT_TRUE(stream->IsSending());
3659
3660 // Get current parameters and change "active" to false.
3661 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
3662 ASSERT_EQ(1u, parameters.encodings.size());
3663 ASSERT_TRUE(parameters.encodings[0].active);
3664 parameters.encodings[0].active = false;
3665 EXPECT_EQ(1u, GetFakeSendStreams().size());
3666 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
3667 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
3668 EXPECT_FALSE(stream->IsSending());
3669
3670 // Reorder the codec list, causing the stream to be reconfigured.
3671 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08003672 parameters2.codecs.push_back(GetEngineCodec("VP9"));
3673 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07003674 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
3675 auto new_streams = GetFakeSendStreams();
3676 // Assert that a new underlying stream was created due to the codec change.
3677 // Otherwise, this test isn't testing what it set out to test.
3678 EXPECT_EQ(1u, GetFakeSendStreams().size());
3679 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
3680
3681 // Verify that we still are not sending anything, due to the inactive
3682 // encoding.
3683 EXPECT_FALSE(new_streams[0]->IsSending());
3684}
3685
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003686// Test that GetRtpSendParameters returns the currently configured codecs.
3687TEST_F(WebRtcVideoChannel2Test, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003688 AddSendStream();
3689 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003690 parameters.codecs.push_back(GetEngineCodec("VP8"));
3691 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003692 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3693
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003694 webrtc::RtpParameters rtp_parameters =
3695 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003696 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08003697 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
3698 rtp_parameters.codecs[0]);
3699 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
3700 rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003701}
3702
3703// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003704TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003705 AddSendStream();
3706 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003707 parameters.codecs.push_back(GetEngineCodec("VP8"));
3708 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003709 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3710
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003711 webrtc::RtpParameters initial_params =
3712 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003713
3714 // We should be able to set the params we just got.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003715 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003716
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003717 // ... And this shouldn't change the params returned by GetRtpSendParameters.
3718 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(last_ssrc_));
3719}
3720
3721// Test that GetRtpReceiveParameters returns the currently configured codecs.
3722TEST_F(WebRtcVideoChannel2Test, GetRtpReceiveParametersCodecs) {
3723 AddRecvStream();
3724 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003725 parameters.codecs.push_back(GetEngineCodec("VP8"));
3726 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003727 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
3728
3729 webrtc::RtpParameters rtp_parameters =
3730 channel_->GetRtpReceiveParameters(last_ssrc_);
3731 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08003732 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
3733 rtp_parameters.codecs[0]);
3734 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
3735 rtp_parameters.codecs[1]);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003736}
3737
johan073ece42016-08-26 02:59:47 -07003738#if defined(WEBRTC_USE_H264)
johan3859c892016-08-05 09:19:25 -07003739TEST_F(WebRtcVideoChannel2Test, GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07003740#else
3741TEST_F(WebRtcVideoChannel2Test, DISABLED_GetRtpReceiveFmtpSprop) {
3742#endif
johan3859c892016-08-05 09:19:25 -07003743 cricket::VideoRecvParameters parameters;
perkj26752742016-10-24 01:21:16 -07003744 cricket::VideoCodec kH264sprop1(101, "H264");
johan3859c892016-08-05 09:19:25 -07003745 kH264sprop1.SetParam("sprop-parameter-sets", "uvw");
3746 parameters.codecs.push_back(kH264sprop1);
perkj26752742016-10-24 01:21:16 -07003747 cricket::VideoCodec kH264sprop2(102, "H264");
johan3859c892016-08-05 09:19:25 -07003748 kH264sprop2.SetParam("sprop-parameter-sets", "xyz");
3749 parameters.codecs.push_back(kH264sprop2);
3750 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
3751
3752 FakeVideoReceiveStream* recv_stream = AddRecvStream();
3753 const webrtc::VideoReceiveStream::Config& cfg = recv_stream->GetConfig();
3754 webrtc::RtpParameters rtp_parameters =
3755 channel_->GetRtpReceiveParameters(last_ssrc_);
3756 ASSERT_EQ(2u, rtp_parameters.codecs.size());
3757 EXPECT_EQ(kH264sprop1.ToCodecParameters(), rtp_parameters.codecs[0]);
3758 ASSERT_EQ(2u, cfg.decoders.size());
3759 EXPECT_EQ(101, cfg.decoders[0].payload_type);
3760 EXPECT_EQ("H264", cfg.decoders[0].payload_name);
3761 std::string sprop;
3762 const webrtc::DecoderSpecificSettings* decoder_specific;
3763 decoder_specific = &cfg.decoders[0].decoder_specific;
3764 ASSERT_TRUE(static_cast<bool>(decoder_specific->h264_extra_settings));
3765 sprop = decoder_specific->h264_extra_settings->sprop_parameter_sets;
3766 EXPECT_EQ("uvw", sprop);
3767
3768 EXPECT_EQ(102, cfg.decoders[1].payload_type);
3769 EXPECT_EQ("H264", cfg.decoders[1].payload_name);
3770 decoder_specific = &cfg.decoders[1].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("xyz", sprop);
3774}
3775
sakal1fd95952016-06-22 00:46:15 -07003776// Test that RtpParameters for receive stream has one encoding and it has
3777// the correct SSRC.
3778TEST_F(WebRtcVideoChannel2Test, RtpEncodingParametersSsrcIsSet) {
3779 AddRecvStream();
3780
3781 webrtc::RtpParameters rtp_parameters =
3782 channel_->GetRtpReceiveParameters(last_ssrc_);
3783 ASSERT_EQ(1u, rtp_parameters.encodings.size());
3784 EXPECT_EQ(rtc::Optional<uint32_t>(last_ssrc_),
3785 rtp_parameters.encodings[0].ssrc);
3786}
3787
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003788// Test that if we set/get parameters multiple times, we get the same results.
3789TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpReceiveParameters) {
3790 AddRecvStream();
3791 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003792 parameters.codecs.push_back(GetEngineCodec("VP8"));
3793 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003794 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
3795
3796 webrtc::RtpParameters initial_params =
3797 channel_->GetRtpReceiveParameters(last_ssrc_);
3798
3799 // We should be able to set the params we just got.
3800 EXPECT_TRUE(channel_->SetRtpReceiveParameters(last_ssrc_, initial_params));
3801
3802 // ... And this shouldn't change the params returned by
3803 // GetRtpReceiveParameters.
3804 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(last_ssrc_));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003805}
3806
Peter Boström3548dd22015-05-22 18:48:36 +02003807void WebRtcVideoChannel2Test::TestReceiverLocalSsrcConfiguration(
3808 bool receiver_first) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003809 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström3548dd22015-05-22 18:48:36 +02003810
3811 const uint32_t kSenderSsrc = 0xC0FFEE;
Peter Boströmdfa28152015-10-21 17:21:10 +02003812 const uint32_t kSecondSenderSsrc = 0xBADCAFE;
Peter Boström3548dd22015-05-22 18:48:36 +02003813 const uint32_t kReceiverSsrc = 0x4711;
Peter Boströmdfa28152015-10-21 17:21:10 +02003814 const uint32_t kExpectedDefaultReceiverSsrc = 1;
Peter Boström3548dd22015-05-22 18:48:36 +02003815
3816 if (receiver_first) {
3817 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
3818 std::vector<FakeVideoReceiveStream*> receive_streams =
3819 fake_call_->GetVideoReceiveStreams();
3820 ASSERT_EQ(1u, receive_streams.size());
Peter Boströmdfa28152015-10-21 17:21:10 +02003821 // Default local SSRC when we have no sender.
3822 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
3823 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02003824 }
3825 AddSendStream(StreamParams::CreateLegacy(kSenderSsrc));
3826 if (!receiver_first)
3827 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
3828 std::vector<FakeVideoReceiveStream*> receive_streams =
3829 fake_call_->GetVideoReceiveStreams();
3830 ASSERT_EQ(1u, receive_streams.size());
3831 EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boströmdfa28152015-10-21 17:21:10 +02003832
3833 // Removing first sender should fall back to another (in this case the second)
3834 // local send stream's SSRC.
3835 AddSendStream(StreamParams::CreateLegacy(kSecondSenderSsrc));
3836 ASSERT_TRUE(channel_->RemoveSendStream(kSenderSsrc));
3837 receive_streams =
3838 fake_call_->GetVideoReceiveStreams();
3839 ASSERT_EQ(1u, receive_streams.size());
3840 EXPECT_EQ(kSecondSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
3841
3842 // Removing the last sender should fall back to default local SSRC.
3843 ASSERT_TRUE(channel_->RemoveSendStream(kSecondSenderSsrc));
3844 receive_streams =
3845 fake_call_->GetVideoReceiveStreams();
3846 ASSERT_EQ(1u, receive_streams.size());
3847 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
3848 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02003849}
3850
3851TEST_F(WebRtcVideoChannel2Test, ConfiguresLocalSsrc) {
3852 TestReceiverLocalSsrcConfiguration(false);
3853}
3854
3855TEST_F(WebRtcVideoChannel2Test, ConfiguresLocalSsrcOnExistingReceivers) {
3856 TestReceiverLocalSsrcConfiguration(true);
3857}
3858
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003859class WebRtcVideoChannel2SimulcastTest : public testing::Test {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003860 public:
skvlad11a9cbf2016-10-07 11:53:05 -07003861 WebRtcVideoChannel2SimulcastTest()
3862 : fake_call_(webrtc::Call::Config(&event_log_)) {}
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003863
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003864 void SetUp() override {
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +02003865 engine_.Init();
nisse51542be2016-02-12 02:27:06 -08003866 channel_.reset(
3867 engine_.CreateChannel(&fake_call_, MediaConfig(), VideoOptions()));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003868 last_ssrc_ = 123;
3869 }
3870
3871 protected:
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003872 void VerifySimulcastSettings(const VideoCodec& codec,
perkj26752742016-10-24 01:21:16 -07003873 int capture_width,
3874 int capture_height,
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003875 size_t num_configured_streams,
pbosbe16f792015-10-16 12:49:39 -07003876 size_t expected_num_streams) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003877 cricket::VideoSendParameters parameters;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003878 parameters.codecs.push_back(codec);
3879 ASSERT_TRUE(channel_->SetSendParameters(parameters));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003880
Peter Boström0c4e06b2015-10-07 12:23:21 +02003881 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
henrikg91d6ede2015-09-17 00:24:34 -07003882 RTC_DCHECK(num_configured_streams <= ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003883 ssrcs.resize(num_configured_streams);
3884
3885 FakeVideoSendStream* stream =
3886 AddSendStream(CreateSimStreamParams("cname", ssrcs));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003887 // Send a full-size frame to trigger a stream reconfiguration to use all
3888 // expected simulcast layers.
3889 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07003890 EXPECT_TRUE(
3891 channel_->SetVideoSend(ssrcs.front(), true, nullptr, &capturer));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003892 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(cricket::VideoFormat(
perkj26752742016-10-24 01:21:16 -07003893 capture_width, capture_height,
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003894 cricket::VideoFormat::FpsToInterval(30),
3895 cricket::FOURCC_I420)));
3896 channel_->SetSend(true);
3897 EXPECT_TRUE(capturer.CaptureFrame());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003898
3899 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
3900 ASSERT_EQ(expected_num_streams, video_streams.size());
3901
3902 std::vector<webrtc::VideoStream> expected_streams = GetSimulcastConfig(
perkj26752742016-10-24 01:21:16 -07003903 num_configured_streams, capture_width, capture_height, 0, kDefaultQpMax,
3904 kDefaultVideoMaxFramerate);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003905
3906 ASSERT_EQ(expected_streams.size(), video_streams.size());
3907
3908 size_t num_streams = video_streams.size();
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003909 int total_max_bitrate_bps = 0;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003910 for (size_t i = 0; i < num_streams; ++i) {
3911 EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
3912 EXPECT_EQ(expected_streams[i].height, video_streams[i].height);
3913
3914 EXPECT_GT(video_streams[i].max_framerate, 0);
3915 EXPECT_EQ(expected_streams[i].max_framerate,
3916 video_streams[i].max_framerate);
3917
3918 EXPECT_GT(video_streams[i].min_bitrate_bps, 0);
3919 EXPECT_EQ(expected_streams[i].min_bitrate_bps,
3920 video_streams[i].min_bitrate_bps);
3921
3922 EXPECT_GT(video_streams[i].target_bitrate_bps, 0);
3923 EXPECT_EQ(expected_streams[i].target_bitrate_bps,
3924 video_streams[i].target_bitrate_bps);
3925
3926 EXPECT_GT(video_streams[i].max_bitrate_bps, 0);
3927 EXPECT_EQ(expected_streams[i].max_bitrate_bps,
3928 video_streams[i].max_bitrate_bps);
3929
3930 EXPECT_GT(video_streams[i].max_qp, 0);
3931 EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp);
3932
3933 EXPECT_FALSE(expected_streams[i].temporal_layer_thresholds_bps.empty());
3934 EXPECT_EQ(expected_streams[i].temporal_layer_thresholds_bps,
3935 video_streams[i].temporal_layer_thresholds_bps);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003936
3937 if (i == num_streams - 1) {
3938 total_max_bitrate_bps += video_streams[i].max_bitrate_bps;
3939 } else {
3940 total_max_bitrate_bps += video_streams[i].target_bitrate_bps;
3941 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003942 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003943
deadbeef5a4a75a2016-06-02 16:23:38 -07003944 EXPECT_TRUE(channel_->SetVideoSend(ssrcs.front(), true, nullptr, nullptr));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003945 }
3946
3947 FakeVideoSendStream* AddSendStream() {
3948 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++));
3949 }
3950
3951 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
3952 size_t num_streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003953 fake_call_.GetVideoSendStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003954 EXPECT_TRUE(channel_->AddSendStream(sp));
3955 std::vector<FakeVideoSendStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003956 fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003957 EXPECT_EQ(num_streams + 1, streams.size());
3958 return streams[streams.size() - 1];
3959 }
3960
3961 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003962 return fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003963 }
3964
3965 FakeVideoReceiveStream* AddRecvStream() {
3966 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++));
3967 }
3968
3969 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
3970 size_t num_streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003971 fake_call_.GetVideoReceiveStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003972 EXPECT_TRUE(channel_->AddRecvStream(sp));
3973 std::vector<FakeVideoReceiveStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003974 fake_call_.GetVideoReceiveStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003975 EXPECT_EQ(num_streams + 1, streams.size());
3976 return streams[streams.size() - 1];
3977 }
3978
skvlad11a9cbf2016-10-07 11:53:05 -07003979 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003980 FakeCall fake_call_;
3981 WebRtcVideoEngine2 engine_;
kwiberg686a8ef2016-02-26 03:00:35 -08003982 std::unique_ptr<VideoMediaChannel> channel_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02003983 uint32_t last_ssrc_;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003984};
3985
3986TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith2SimulcastStreams) {
magjed509e4fe2016-11-18 01:34:11 -08003987 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 640, 360, 2, 2);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003988}
3989
3990TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith3SimulcastStreams) {
magjed509e4fe2016-11-18 01:34:11 -08003991 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003992}
3993
3994// Test that we normalize send codec format size in simulcast.
3995TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
magjed509e4fe2016-11-18 01:34:11 -08003996 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 541, 271, 2, 2);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003997}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003998} // namespace cricket