blob: c3d344672451849421ef95d76eb7e85e0b9399a1 [file] [log] [blame]
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00009 */
10
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +000011#include <algorithm>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000012#include <map>
kwiberg686a8ef2016-02-26 03:00:35 -080013#include <memory>
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000014#include <vector>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000015
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -070016#include "api/test/mock_video_decoder_factory.h"
17#include "api/test/mock_video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "api/video_codecs/sdp_video_format.h"
19#include "api/video_codecs/video_decoder_factory.h"
20#include "api/video_codecs/video_encoder.h"
21#include "api/video_codecs/video_encoder_factory.h"
22#include "call/flexfec_receive_stream.h"
23#include "common_video/h264/profile_level_id.h"
24#include "logging/rtc_event_log/rtc_event_log.h"
25#include "media/base/mediaconstants.h"
26#include "media/base/rtputils.h"
27#include "media/base/testutils.h"
28#include "media/base/videoengine_unittest.h"
29#include "media/engine/constants.h"
30#include "media/engine/fakewebrtccall.h"
31#include "media/engine/fakewebrtcvideoengine.h"
32#include "media/engine/simulcast.h"
33#include "media/engine/webrtcvideoengine.h"
34#include "media/engine/webrtcvoiceengine.h"
35#include "rtc_base/arraysize.h"
36#include "rtc_base/gunit.h"
37#include "rtc_base/stringutils.h"
38#include "test/field_trial.h"
39#include "test/gmock.h"
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000040
isheriff6f8d6862016-05-26 11:24:55 -070041using webrtc::RtpExtension;
42
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000043namespace {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000044static const int kDefaultQpMax = 56;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000045
noahricd10a68e2015-07-10 11:27:55 -070046static const uint8_t kRedRtxPayloadType = 125;
47
Peter Boström0c4e06b2015-10-07 12:23:21 +020048static const uint32_t kSsrcs1[] = {1};
49static const uint32_t kSsrcs3[] = {1, 2, 3};
50static const uint32_t kRtxSsrcs1[] = {4};
brandtr468da7c2016-11-22 02:16:47 -080051static const uint32_t kFlexfecSsrc = 5;
Peter Boström0c4e06b2015-10-07 12:23:21 +020052static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE;
mzanaty8a855d62017-02-17 15:46:43 -080053static const uint32_t kDefaultRecvSsrc = 0;
54
pbos@webrtc.org3c107582014-07-20 15:27:35 +000055static const char kUnsupportedExtensionName[] =
56 "urn:ietf:params:rtp-hdrext:unsupported";
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000057
magjed509e4fe2016-11-18 01:34:11 -080058cricket::VideoCodec RemoveFeedbackParams(cricket::VideoCodec&& codec) {
59 codec.feedback_params = cricket::FeedbackParams();
60 return codec;
61}
62
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000063void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) {
64 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
65 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
66 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
67 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
68 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
69 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
70 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
stefan43edf0f2015-11-20 18:05:48 -080071 cricket::kRtcpFbParamTransportCc, cricket::kParamValueEmpty)));
72 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000073 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
74}
75
magjed725e4842016-11-16 00:48:13 -080076// Return true if any codec in |codecs| is an RTX codec with associated payload
77// type |payload_type|.
78bool HasRtxCodec(const std::vector<cricket::VideoCodec>& codecs,
79 int payload_type) {
80 for (const cricket::VideoCodec& codec : codecs) {
81 int associated_payload_type;
82 if (cricket::CodecNamesEq(codec.name.c_str(), "rtx") &&
83 codec.GetParam(cricket::kCodecParamAssociatedPayloadType,
84 &associated_payload_type) &&
85 associated_payload_type == payload_type) {
86 return true;
87 }
88 }
89 return false;
90}
91
nisseca5706d2017-09-11 02:32:16 -070092// TODO(nisse): Duplicated in call.cc.
93const int* FindKeyByValue(const std::map<int, int>& m, int v) {
94 for (const auto& kv : m) {
95 if (kv.second == v)
96 return &kv.first;
97 }
98 return nullptr;
99}
100
101bool HasRtxReceiveAssociation(
102 const webrtc::VideoReceiveStream::Config& config,
103 int payload_type) {
104 return FindKeyByValue(config.rtp.rtx_associated_payload_types,
105 payload_type) != nullptr;
106}
107
108// Check that there's an Rtx payload type for each decoder.
109bool VerifyRtxReceiveAssociations(
110 const webrtc::VideoReceiveStream::Config& config) {
111 for (const auto& decoder : config.decoders) {
112 if (!HasRtxReceiveAssociation(config, decoder.payload_type))
113 return false;
114 }
115 return true;
116}
117
brandtrffc61182016-11-28 06:02:22 -0800118rtc::scoped_refptr<webrtc::VideoFrameBuffer> CreateBlackFrameBuffer(
nisse64ec8f82016-09-27 00:17:25 -0700119 int width,
120 int height) {
121 rtc::scoped_refptr<webrtc::I420Buffer> buffer =
122 webrtc::I420Buffer::Create(width, height);
nisseaf916892017-01-10 07:44:26 -0800123 webrtc::I420Buffer::SetBlack(buffer);
nisse64ec8f82016-09-27 00:17:25 -0700124 return buffer;
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +0000125}
126
Shao Changbine62202f2015-04-21 20:24:50 +0800127void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config,
128 const std::map<int, int>& rtx_types) {
129 std::map<int, int>::const_iterator it;
130 it = rtx_types.find(config.encoder_settings.payload_type);
131 EXPECT_TRUE(it != rtx_types.end() &&
132 it->second == config.rtp.rtx.payload_type);
133
brandtrb5f2c3f2016-10-04 23:28:39 -0700134 if (config.rtp.ulpfec.red_rtx_payload_type != -1) {
135 it = rtx_types.find(config.rtp.ulpfec.red_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800136 EXPECT_TRUE(it != rtx_types.end() &&
brandtrb5f2c3f2016-10-04 23:28:39 -0700137 it->second == config.rtp.ulpfec.red_rtx_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800138 }
139}
kthelgason2bc68642017-02-07 07:02:22 -0800140
141cricket::MediaConfig GetMediaConfig() {
142 cricket::MediaConfig media_config;
143 media_config.video.enable_cpu_overuse_detection = false;
144 return media_config;
145}
nisse26e3abb2017-08-25 04:44:25 -0700146
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000147} // namespace
148
149namespace cricket {
eladalonf1841382017-06-12 01:16:46 -0700150class WebRtcVideoEngineTest : public ::testing::Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000151 public:
eladalonf1841382017-06-12 01:16:46 -0700152 WebRtcVideoEngineTest() : WebRtcVideoEngineTest("") {}
153 explicit WebRtcVideoEngineTest(const char* field_trials)
stefanc1aeaf02015-10-15 07:26:07 -0700154 : override_field_trials_(field_trials),
skvlad11a9cbf2016-10-07 11:53:05 -0700155 call_(webrtc::Call::Create(webrtc::Call::Config(&event_log_))),
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200156 encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
157 decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
158 engine_(std::unique_ptr<cricket::WebRtcVideoEncoderFactory>(
159 encoder_factory_),
160 std::unique_ptr<cricket::WebRtcVideoDecoderFactory>(
161 decoder_factory_)) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000162 std::vector<VideoCodec> engine_codecs = engine_.codecs();
henrikg91d6ede2015-09-17 00:24:34 -0700163 RTC_DCHECK(!engine_codecs.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000164 bool codec_set = false;
magjed509e4fe2016-11-18 01:34:11 -0800165 for (const cricket::VideoCodec& codec : engine_codecs) {
166 if (codec.name == "rtx") {
Shao Changbine62202f2015-04-21 20:24:50 +0800167 int associated_payload_type;
magjed509e4fe2016-11-18 01:34:11 -0800168 if (codec.GetParam(kCodecParamAssociatedPayloadType,
169 &associated_payload_type)) {
170 default_apt_rtx_types_[associated_payload_type] = codec.id;
Shao Changbine62202f2015-04-21 20:24:50 +0800171 }
magjed509e4fe2016-11-18 01:34:11 -0800172 } else if (!codec_set && codec.name != "red" && codec.name != "ulpfec") {
173 default_codec_ = codec;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000174 codec_set = true;
175 }
176 }
177
henrikg91d6ede2015-09-17 00:24:34 -0700178 RTC_DCHECK(codec_set);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000179 }
180
181 protected:
magjed509e4fe2016-11-18 01:34:11 -0800182 // Find the codec in the engine with the given name. The codec must be
183 // present.
184 cricket::VideoCodec GetEngineCodec(const std::string& name);
185
magjed2475ae22017-09-12 04:42:15 -0700186 VideoMediaChannel* SetUpForExternalEncoderFactory();
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000187
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000188 VideoMediaChannel* SetUpForExternalDecoderFactory(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000189 const std::vector<VideoCodec>& codecs);
190
Peter Boströme4499152016-02-05 11:13:28 +0100191 void TestExtendedEncoderOveruse(bool use_external_encoder);
192
stefanc1aeaf02015-10-15 07:26:07 -0700193 webrtc::test::ScopedFieldTrials override_field_trials_;
skvlad11a9cbf2016-10-07 11:53:05 -0700194 webrtc::RtcEventLogNullImpl event_log_;
eladalonf1841382017-06-12 01:16:46 -0700195 // Used in WebRtcVideoEngineVoiceTest, but defined here so it's properly
pbos@webrtc.orgf1f0d9a2015-03-02 13:30:15 +0000196 // initialized when the constructor is called.
kwiberg686a8ef2016-02-26 03:00:35 -0800197 std::unique_ptr<webrtc::Call> call_;
Magnus Jedvertd4b0c052017-09-14 10:24:54 +0200198 // TODO(magjed): Update all tests to use new video codec factories once the
199 // old factories are deprecated,
200 // https://bugs.chromium.org/p/webrtc/issues/detail?id=7925.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200201 // These factories are owned by the video engine.
202 cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
203 cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
eladalonf1841382017-06-12 01:16:46 -0700204 WebRtcVideoEngine engine_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000205 VideoCodec default_codec_;
Shao Changbine62202f2015-04-21 20:24:50 +0800206 std::map<int, int> default_apt_rtx_types_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000207};
208
eladalonf1841382017-06-12 01:16:46 -0700209TEST_F(WebRtcVideoEngineTest, AnnouncesVp9AccordingToBuildFlags) {
Peter Boström12996152016-05-14 02:03:18 +0200210 bool claims_vp9_support = false;
211 for (const cricket::VideoCodec& codec : engine_.codecs()) {
212 if (codec.name == "VP9") {
213 claims_vp9_support = true;
214 break;
215 }
216 }
217#if defined(RTC_DISABLE_VP9)
218 EXPECT_FALSE(claims_vp9_support);
219#else
220 EXPECT_TRUE(claims_vp9_support);
221#endif // defined(RTC_DISABLE_VP9)
222}
223
eladalonf1841382017-06-12 01:16:46 -0700224TEST_F(WebRtcVideoEngineTest, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000225 std::vector<VideoCodec> engine_codecs = engine_.codecs();
226 for (size_t i = 0; i < engine_codecs.size(); ++i) {
227 if (engine_codecs[i].name != kRtxCodecName)
228 continue;
229 int associated_payload_type;
230 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000231 &associated_payload_type));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000232 EXPECT_EQ(default_codec_.id, associated_payload_type);
233 return;
234 }
235 FAIL() << "No RTX codec found among default codecs.";
236}
237
eladalonf1841382017-06-12 01:16:46 -0700238TEST_F(WebRtcVideoEngineTest, SupportsTimestampOffsetHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100239 RtpCapabilities capabilities = engine_.GetCapabilities();
240 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700241 for (const RtpExtension& extension : capabilities.header_extensions) {
242 if (extension.uri == RtpExtension::kTimestampOffsetUri) {
243 EXPECT_EQ(RtpExtension::kTimestampOffsetDefaultId, extension.id);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000244 return;
245 }
246 }
247 FAIL() << "Timestamp offset extension not in header-extension list.";
248}
249
eladalonf1841382017-06-12 01:16:46 -0700250TEST_F(WebRtcVideoEngineTest, SupportsAbsoluteSenderTimeHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100251 RtpCapabilities capabilities = engine_.GetCapabilities();
252 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700253 for (const RtpExtension& extension : capabilities.header_extensions) {
254 if (extension.uri == RtpExtension::kAbsSendTimeUri) {
255 EXPECT_EQ(RtpExtension::kAbsSendTimeDefaultId, extension.id);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000256 return;
257 }
258 }
259 FAIL() << "Absolute Sender Time extension not in header-extension list.";
260}
261
eladalonf1841382017-06-12 01:16:46 -0700262TEST_F(WebRtcVideoEngineTest, SupportsTransportSequenceNumberHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100263 RtpCapabilities capabilities = engine_.GetCapabilities();
264 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700265 for (const RtpExtension& extension : capabilities.header_extensions) {
266 if (extension.uri == RtpExtension::kTransportSequenceNumberUri) {
267 EXPECT_EQ(RtpExtension::kTransportSequenceNumberDefaultId, extension.id);
stefanc1aeaf02015-10-15 07:26:07 -0700268 return;
269 }
270 }
271 FAIL() << "Transport sequence number extension not in header-extension list.";
272}
273
eladalonf1841382017-06-12 01:16:46 -0700274TEST_F(WebRtcVideoEngineTest, SupportsVideoRotationHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100275 RtpCapabilities capabilities = engine_.GetCapabilities();
276 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700277 for (const RtpExtension& extension : capabilities.header_extensions) {
278 if (extension.uri == RtpExtension::kVideoRotationUri) {
279 EXPECT_EQ(RtpExtension::kVideoRotationDefaultId, extension.id);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700280 return;
281 }
282 }
283 FAIL() << "Video Rotation extension not in header-extension list.";
284}
285
eladalonf1841382017-06-12 01:16:46 -0700286TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeCapturer) {
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700287 // Allocate the capturer first to prevent early destruction before channel's
288 // dtor is called.
289 cricket::FakeVideoCapturer capturer;
290
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200291 encoder_factory_->AddSupportedVideoCodecType("VP8");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700292
magjed2475ae22017-09-12 04:42:15 -0700293 std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700294 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
295
296 // Add CVO extension.
297 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800298 cricket::VideoSendParameters parameters;
299 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200300 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700301 RtpExtension(RtpExtension::kVideoRotationUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200302 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700303
304 // Set capturer.
deadbeef5a4a75a2016-06-02 16:23:38 -0700305 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700306
307 // Verify capturer has turned off applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700308 EXPECT_FALSE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700309
310 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200311 parameters.extensions.clear();
312 EXPECT_TRUE(channel->SetSendParameters(parameters));
nisse47ac4622016-05-25 08:47:01 -0700313 EXPECT_TRUE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700314}
315
eladalonf1841382017-06-12 01:16:46 -0700316TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeAddSendStream) {
perkj91e1c152016-03-02 05:34:00 -0800317 // Allocate the capturer first to prevent early destruction before channel's
318 // dtor is called.
319 cricket::FakeVideoCapturer capturer;
320
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200321 encoder_factory_->AddSupportedVideoCodecType("VP8");
perkj91e1c152016-03-02 05:34:00 -0800322
magjed2475ae22017-09-12 04:42:15 -0700323 std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
perkj91e1c152016-03-02 05:34:00 -0800324 // Add CVO extension.
325 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800326 cricket::VideoSendParameters parameters;
327 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj91e1c152016-03-02 05:34:00 -0800328 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700329 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkj91e1c152016-03-02 05:34:00 -0800330 EXPECT_TRUE(channel->SetSendParameters(parameters));
331 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
332
333 // Set capturer.
deadbeef5a4a75a2016-06-02 16:23:38 -0700334 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
perkj91e1c152016-03-02 05:34:00 -0800335
336 // Verify capturer has turned off applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700337 EXPECT_FALSE(capturer.apply_rotation());
perkj91e1c152016-03-02 05:34:00 -0800338}
339
eladalonf1841382017-06-12 01:16:46 -0700340TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionAfterCapturer) {
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700341 cricket::FakeVideoCapturer capturer;
342
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200343 encoder_factory_->AddSupportedVideoCodecType("VP8");
344 encoder_factory_->AddSupportedVideoCodecType("VP9");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700345
magjed2475ae22017-09-12 04:42:15 -0700346 std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700347 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
348
349 // Set capturer.
deadbeef5a4a75a2016-06-02 16:23:38 -0700350 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700351
perkjcaafdba2016-03-20 07:34:29 -0700352 // Verify capturer has turned on applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700353 EXPECT_TRUE(capturer.apply_rotation());
perkjcaafdba2016-03-20 07:34:29 -0700354
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700355 // Add CVO extension.
356 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800357 cricket::VideoSendParameters parameters;
358 parameters.codecs.push_back(GetEngineCodec("VP8"));
359 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200360 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700361 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkjcaafdba2016-03-20 07:34:29 -0700362 // Also remove the first codec to trigger a codec change as well.
363 parameters.codecs.erase(parameters.codecs.begin());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200364 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700365
366 // Verify capturer has turned off applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700367 EXPECT_FALSE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700368
369 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200370 parameters.extensions.clear();
371 EXPECT_TRUE(channel->SetSendParameters(parameters));
nisse47ac4622016-05-25 08:47:01 -0700372 EXPECT_TRUE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700373}
374
eladalonf1841382017-06-12 01:16:46 -0700375TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) {
kwiberg686a8ef2016-02-26 03:00:35 -0800376 std::unique_ptr<VideoMediaChannel> channel(
kthelgason2bc68642017-02-07 07:02:22 -0800377 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000378
379 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
380
381 EXPECT_FALSE(channel->SetSend(true))
382 << "Channel should not start without codecs.";
383 EXPECT_TRUE(channel->SetSend(false))
384 << "Channel should be stoppable even without set codecs.";
385}
386
eladalonf1841382017-06-12 01:16:46 -0700387TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) {
kwiberg686a8ef2016-02-26 03:00:35 -0800388 std::unique_ptr<VideoMediaChannel> channel(
kthelgason2bc68642017-02-07 07:02:22 -0800389 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000390 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
391 VideoMediaInfo info;
392 channel->GetStats(&info);
393}
394
eladalonf1841382017-06-12 01:16:46 -0700395TEST_F(WebRtcVideoEngineTest, UseExternalFactoryForVp8WhenSupported) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200396 encoder_factory_->AddSupportedVideoCodecType("VP8");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000397
magjed2475ae22017-09-12 04:42:15 -0700398 std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
Sergey Ulanove2b15012016-11-22 16:08:30 -0800399 channel->OnReadyToSend(true);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000400
401 EXPECT_TRUE(
402 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200403 EXPECT_EQ(0, encoder_factory_->GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000404 EXPECT_TRUE(channel->SetSend(true));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000405 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700406 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000407 EXPECT_EQ(cricket::CS_RUNNING,
408 capturer.Start(capturer.GetSupportedFormats()->front()));
409 EXPECT_TRUE(capturer.CaptureFrame());
Per21d45d22016-10-30 21:37:57 +0100410 // Sending one frame will have allocate the encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200411 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
412 EXPECT_TRUE_WAIT(encoder_factory_->encoders()[0]->GetNumEncodedFrames() > 0,
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000413 kTimeout);
414
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200415 int num_created_encoders = encoder_factory_->GetNumCreatedEncoders();
Per21d45d22016-10-30 21:37:57 +0100416 EXPECT_EQ(num_created_encoders, 1);
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000417
418 // Setting codecs of the same type should not reallocate any encoders
419 // (expecting a no-op).
magjed509e4fe2016-11-18 01:34:11 -0800420 cricket::VideoSendParameters parameters;
421 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200422 EXPECT_TRUE(channel->SetSendParameters(parameters));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200423 EXPECT_EQ(num_created_encoders, encoder_factory_->GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000424
425 // Remove stream previously added to free the external encoder instance.
426 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200427 EXPECT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000428}
429
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700430// Test that when an external encoder factory supports a codec we don't
431// internally support, we still add an RTX codec for it.
432// TODO(deadbeef): Currently this test is only effective if WebRTC is
433// built with no internal H264 support. This test should be updated
434// if/when we start adding RTX codecs for unrecognized codec names.
eladalonf1841382017-06-12 01:16:46 -0700435TEST_F(WebRtcVideoEngineTest, RtxCodecAddedForExternalCodec) {
magjed725e4842016-11-16 00:48:13 -0800436 using webrtc::H264::ProfileLevelIdToString;
437 using webrtc::H264::ProfileLevelId;
438 using webrtc::H264::kLevel1;
439 cricket::VideoCodec h264_constrained_baseline("H264");
440 h264_constrained_baseline.params[kH264FmtpProfileLevelId] =
441 *ProfileLevelIdToString(
442 ProfileLevelId(webrtc::H264::kProfileConstrainedBaseline, kLevel1));
443 cricket::VideoCodec h264_constrained_high("H264");
444 h264_constrained_high.params[kH264FmtpProfileLevelId] =
445 *ProfileLevelIdToString(
446 ProfileLevelId(webrtc::H264::kProfileConstrainedHigh, kLevel1));
447 cricket::VideoCodec h264_high("H264");
448 h264_high.params[kH264FmtpProfileLevelId] = *ProfileLevelIdToString(
449 ProfileLevelId(webrtc::H264::kProfileHigh, kLevel1));
450
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200451 encoder_factory_->AddSupportedVideoCodec(h264_constrained_baseline);
452 encoder_factory_->AddSupportedVideoCodec(h264_constrained_high);
453 encoder_factory_->AddSupportedVideoCodec(h264_high);
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700454
magjed725e4842016-11-16 00:48:13 -0800455 // First figure out what payload types the test codecs got assigned.
456 const std::vector<cricket::VideoCodec> codecs = engine_.codecs();
magjed509e4fe2016-11-18 01:34:11 -0800457 // Now search for RTX codecs for them. Expect that they all have associated
458 // RTX codecs.
magjed725e4842016-11-16 00:48:13 -0800459 EXPECT_TRUE(HasRtxCodec(
460 codecs, FindMatchingCodec(codecs, h264_constrained_baseline)->id));
461 EXPECT_TRUE(HasRtxCodec(
462 codecs, FindMatchingCodec(codecs, h264_constrained_high)->id));
magjed509e4fe2016-11-18 01:34:11 -0800463 EXPECT_TRUE(HasRtxCodec(
magjed725e4842016-11-16 00:48:13 -0800464 codecs, FindMatchingCodec(codecs, h264_high)->id));
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700465}
466
eladalonf1841382017-06-12 01:16:46 -0700467void WebRtcVideoEngineTest::TestExtendedEncoderOveruse(
Peter Boströme4499152016-02-05 11:13:28 +0100468 bool use_external_encoder) {
kwiberg686a8ef2016-02-26 03:00:35 -0800469 std::unique_ptr<VideoMediaChannel> channel;
skvlad11a9cbf2016-10-07 11:53:05 -0700470 FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_));
Peter Boströme4499152016-02-05 11:13:28 +0100471 call_.reset(fake_call);
472 if (use_external_encoder) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200473 encoder_factory_->AddSupportedVideoCodecType("VP8");
magjed2475ae22017-09-12 04:42:15 -0700474 channel.reset(SetUpForExternalEncoderFactory());
Peter Boströme4499152016-02-05 11:13:28 +0100475 } else {
nisse51542be2016-02-12 02:27:06 -0800476 channel.reset(
kthelgason2bc68642017-02-07 07:02:22 -0800477 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
Peter Boströme4499152016-02-05 11:13:28 +0100478 }
479 ASSERT_TRUE(
480 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
magjed509e4fe2016-11-18 01:34:11 -0800481 cricket::VideoSendParameters parameters;
482 parameters.codecs.push_back(GetEngineCodec("VP8"));
Peter Boströme4499152016-02-05 11:13:28 +0100483 EXPECT_TRUE(channel->SetSendParameters(parameters));
484 EXPECT_TRUE(channel->SetSend(true));
485 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
486
487 EXPECT_EQ(use_external_encoder,
488 stream->GetConfig().encoder_settings.full_overuse_time);
489 // Remove stream previously added to free the external encoder instance.
490 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
491}
492
eladalonf1841382017-06-12 01:16:46 -0700493TEST_F(WebRtcVideoEngineTest, EnablesFullEncoderTimeForExternalEncoders) {
Peter Boströme4499152016-02-05 11:13:28 +0100494 TestExtendedEncoderOveruse(true);
495}
496
eladalonf1841382017-06-12 01:16:46 -0700497TEST_F(WebRtcVideoEngineTest, DisablesFullEncoderTimeForNonExternalEncoders) {
Peter Boströme4499152016-02-05 11:13:28 +0100498 TestExtendedEncoderOveruse(false);
499}
500
Peter Boström12996152016-05-14 02:03:18 +0200501#if !defined(RTC_DISABLE_VP9)
eladalonf1841382017-06-12 01:16:46 -0700502TEST_F(WebRtcVideoEngineTest, CanConstructDecoderForVp9EncoderFactory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200503 encoder_factory_->AddSupportedVideoCodecType("VP9");
Peter Boström53eda3d2015-03-27 15:53:18 +0100504
magjed2475ae22017-09-12 04:42:15 -0700505 std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
Peter Boström53eda3d2015-03-27 15:53:18 +0100506
507 EXPECT_TRUE(
508 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
509}
Peter Boström12996152016-05-14 02:03:18 +0200510#endif // !defined(RTC_DISABLE_VP9)
Peter Boström53eda3d2015-03-27 15:53:18 +0100511
eladalonf1841382017-06-12 01:16:46 -0700512TEST_F(WebRtcVideoEngineTest, PropagatesInputFrameTimestamp) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200513 encoder_factory_->AddSupportedVideoCodecType("VP8");
skvlad11a9cbf2016-10-07 11:53:05 -0700514 FakeCall* fake_call = new FakeCall(webrtc::Call::Config(&event_log_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200515 call_.reset(fake_call);
magjed2475ae22017-09-12 04:42:15 -0700516 std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
qiangchenc27d89f2015-07-16 10:27:16 -0700517
518 EXPECT_TRUE(
519 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
520
521 FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700522 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
qiangchenc27d89f2015-07-16 10:27:16 -0700523 capturer.Start(cricket::VideoFormat(1280, 720,
524 cricket::VideoFormat::FpsToInterval(60),
525 cricket::FOURCC_I420));
526 channel->SetSend(true);
527
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200528 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
qiangchenc27d89f2015-07-16 10:27:16 -0700529
530 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700531 int64_t last_timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700532 for (int i = 0; i < 10; i++) {
533 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700534 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700535 int64_t interval = timestamp - last_timestamp;
536
537 // Precision changes from nanosecond to millisecond.
538 // Allow error to be no more than 1.
539 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1);
540
541 last_timestamp = timestamp;
542 }
543
544 capturer.Start(cricket::VideoFormat(1280, 720,
545 cricket::VideoFormat::FpsToInterval(30),
546 cricket::FOURCC_I420));
547
548 EXPECT_TRUE(capturer.CaptureFrame());
549 last_timestamp = stream->GetLastTimestamp();
550 for (int i = 0; i < 10; i++) {
551 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700552 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700553 int64_t interval = timestamp - last_timestamp;
554
555 // Precision changes from nanosecond to millisecond.
556 // Allow error to be no more than 1.
557 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1);
558
559 last_timestamp = timestamp;
560 }
561
562 // Remove stream previously added to free the external encoder instance.
563 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
564}
565
eladalonf1841382017-06-12 01:16:46 -0700566cricket::VideoCodec WebRtcVideoEngineTest::GetEngineCodec(
magjed509e4fe2016-11-18 01:34:11 -0800567 const std::string& name) {
568 for (const cricket::VideoCodec& engine_codec : engine_.codecs()) {
Magnus Jedvert8deb8182017-10-05 13:13:32 +0200569 if (!CodecNamesEq(name, engine_codec.name))
570 continue;
571 // The tests only use H264 Constrained Baseline. Make sure we don't return
572 // an internal H264 codec from the engine with a different H264 profile.
573 if (CodecNamesEq(name.c_str(), kH264CodecName)) {
574 const rtc::Optional<webrtc::H264::ProfileLevelId> profile_level_id =
575 webrtc::H264::ParseSdpProfileLevelId(engine_codec.params);
576 if (profile_level_id->profile !=
577 webrtc::H264::kProfileConstrainedBaseline) {
578 continue;
579 }
580 }
581 return engine_codec;
magjed509e4fe2016-11-18 01:34:11 -0800582 }
583 // This point should never be reached.
584 ADD_FAILURE() << "Unrecognized codec name: " << name;
585 return cricket::VideoCodec();
586}
587
magjed2475ae22017-09-12 04:42:15 -0700588VideoMediaChannel* WebRtcVideoEngineTest::SetUpForExternalEncoderFactory() {
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000589 VideoMediaChannel* channel =
kthelgason2bc68642017-02-07 07:02:22 -0800590 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200591 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800592 // We need to look up the codec in the engine to get the correct payload type.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200593 for (const VideoCodec& codec : encoder_factory_->supported_codecs())
magjed509e4fe2016-11-18 01:34:11 -0800594 parameters.codecs.push_back(GetEngineCodec(codec.name));
595
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200596 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000597
598 return channel;
599}
600
eladalonf1841382017-06-12 01:16:46 -0700601VideoMediaChannel* WebRtcVideoEngineTest::SetUpForExternalDecoderFactory(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000602 const std::vector<VideoCodec>& codecs) {
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000603 VideoMediaChannel* channel =
kthelgason2bc68642017-02-07 07:02:22 -0800604 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200605 cricket::VideoRecvParameters parameters;
606 parameters.codecs = codecs;
607 EXPECT_TRUE(channel->SetRecvParameters(parameters));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000608
609 return channel;
610}
611
eladalonf1841382017-06-12 01:16:46 -0700612TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200613 encoder_factory_->AddSupportedVideoCodecType("VP8");
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000614
magjed2475ae22017-09-12 04:42:15 -0700615 std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000616
Peter Boström0c4e06b2015-10-07 12:23:21 +0200617 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000618
619 EXPECT_TRUE(
620 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
621 EXPECT_TRUE(channel->SetSend(true));
622
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000623 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700624 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, &capturer));
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000625 EXPECT_EQ(cricket::CS_RUNNING,
626 capturer.Start(capturer.GetSupportedFormats()->front()));
627 EXPECT_TRUE(capturer.CaptureFrame());
628
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200629 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000630
631 // Verify that encoders are configured for simulcast through adapter
632 // (increasing resolution and only configured to send one stream each).
633 int prev_width = -1;
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200634 for (size_t i = 0; i < encoder_factory_->encoders().size(); ++i) {
635 ASSERT_TRUE(encoder_factory_->encoders()[i]->WaitForInitEncode());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000636 webrtc::VideoCodec codec_settings =
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200637 encoder_factory_->encoders()[i]->GetCodecSettings();
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000638 EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
639 EXPECT_GT(codec_settings.width, prev_width);
640 prev_width = codec_settings.width;
641 }
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000642
deadbeef5a4a75a2016-06-02 16:23:38 -0700643 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, nullptr));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000644
645 channel.reset();
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200646 ASSERT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000647}
648
eladalonf1841382017-06-12 01:16:46 -0700649TEST_F(WebRtcVideoEngineTest, ChannelWithExternalH264CanChangeToInternalVp8) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200650 encoder_factory_->AddSupportedVideoCodecType("H264");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000651
magjed2475ae22017-09-12 04:42:15 -0700652 std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000653
654 EXPECT_TRUE(
655 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200656 ASSERT_EQ(1u, encoder_factory_->encoders().size());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000657
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200658 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800659 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200660 EXPECT_TRUE(channel->SetSendParameters(parameters));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200661 ASSERT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000662}
663
eladalonf1841382017-06-12 01:16:46 -0700664TEST_F(WebRtcVideoEngineTest,
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000665 DontUseExternalEncoderFactoryForUnsupportedCodecs) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200666 encoder_factory_->AddSupportedVideoCodecType("H264");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000667
kwiberg686a8ef2016-02-26 03:00:35 -0800668 std::unique_ptr<VideoMediaChannel> channel(
kthelgason2bc68642017-02-07 07:02:22 -0800669 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
magjed509e4fe2016-11-18 01:34:11 -0800670 cricket::VideoSendParameters parameters;
671 parameters.codecs.push_back(GetEngineCodec("VP8"));
672 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000673
674 EXPECT_TRUE(
675 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000676 // Make sure DestroyVideoEncoder was called on the factory.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200677 ASSERT_EQ(0u, encoder_factory_->encoders().size());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000678}
679
eladalonf1841382017-06-12 01:16:46 -0700680TEST_F(WebRtcVideoEngineTest,
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000681 UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200682 encoder_factory_->AddSupportedVideoCodecType("VP8");
683 encoder_factory_->AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000684
kwiberg686a8ef2016-02-26 03:00:35 -0800685 std::unique_ptr<VideoMediaChannel> channel(
kthelgason2bc68642017-02-07 07:02:22 -0800686 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
magjed509e4fe2016-11-18 01:34:11 -0800687 cricket::VideoSendParameters parameters;
688 parameters.codecs.push_back(GetEngineCodec("VP8"));
689 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000690
Peter Boström0c4e06b2015-10-07 12:23:21 +0200691 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000692
693 EXPECT_TRUE(
694 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
695 EXPECT_TRUE(channel->SetSend(true));
696
697 // Send a fake frame, or else the media engine will configure the simulcast
698 // encoder adapter at a low-enough size that it'll only create a single
699 // encoder layer.
700 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700701 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, &capturer));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000702 EXPECT_EQ(cricket::CS_RUNNING,
703 capturer.Start(capturer.GetSupportedFormats()->front()));
704 EXPECT_TRUE(capturer.CaptureFrame());
705
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200706 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
707 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000708 EXPECT_EQ(webrtc::kVideoCodecVP8,
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200709 encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000710
711 channel.reset();
712 // Make sure DestroyVideoEncoder was called on the factory.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200713 EXPECT_EQ(0u, encoder_factory_->encoders().size());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000714}
715
eladalonf1841382017-06-12 01:16:46 -0700716TEST_F(WebRtcVideoEngineTest,
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000717 DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200718 encoder_factory_->AddSupportedVideoCodecType("VP8");
719 encoder_factory_->AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000720
kwiberg686a8ef2016-02-26 03:00:35 -0800721 std::unique_ptr<VideoMediaChannel> channel(
kthelgason2bc68642017-02-07 07:02:22 -0800722 engine_.CreateChannel(call_.get(), GetMediaConfig(), VideoOptions()));
magjed509e4fe2016-11-18 01:34:11 -0800723 cricket::VideoSendParameters parameters;
724 parameters.codecs.push_back(GetEngineCodec("H264"));
725 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000726
727 EXPECT_TRUE(
728 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200729 ASSERT_EQ(1u, encoder_factory_->encoders().size());
Per21d45d22016-10-30 21:37:57 +0100730
731 // Send a frame of 720p. This should trigger a "real" encoder initialization.
732 cricket::VideoFormat format(
733 1280, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
734 cricket::FakeVideoCapturer capturer;
735 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
736 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format));
737 EXPECT_TRUE(capturer.CaptureFrame());
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200738 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000739 EXPECT_EQ(webrtc::kVideoCodecH264,
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200740 encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000741
742 channel.reset();
743 // Make sure DestroyVideoEncoder was called on the factory.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200744 ASSERT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000745}
746
eladalonf1841382017-06-12 01:16:46 -0700747TEST_F(WebRtcVideoEngineTest, SimulcastDisabledForH264) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200748 encoder_factory_->AddSupportedVideoCodecType("H264");
noahricfdac5162015-08-27 01:59:29 -0700749
magjed2475ae22017-09-12 04:42:15 -0700750 std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
noahricfdac5162015-08-27 01:59:29 -0700751
Peter Boström0c4e06b2015-10-07 12:23:21 +0200752 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
noahricfdac5162015-08-27 01:59:29 -0700753 EXPECT_TRUE(
754 channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs)));
Peter Boströmce23bee2016-02-02 14:14:30 +0100755
756 // Send a frame of 720p. This should trigger a "real" encoder initialization.
noahricfdac5162015-08-27 01:59:29 -0700757 cricket::VideoFormat format(
758 1280, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
Peter Boströmce23bee2016-02-02 14:14:30 +0100759 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700760 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], true, nullptr, &capturer));
Peter Boströmce23bee2016-02-02 14:14:30 +0100761 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format));
762 EXPECT_TRUE(capturer.CaptureFrame());
763
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200764 ASSERT_EQ(1u, encoder_factory_->encoders().size());
765 FakeWebRtcVideoEncoder* encoder = encoder_factory_->encoders()[0];
766 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
noahricfdac5162015-08-27 01:59:29 -0700767 EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
768 EXPECT_EQ(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
deadbeef5a4a75a2016-06-02 16:23:38 -0700769 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], true, nullptr, nullptr));
noahricfdac5162015-08-27 01:59:29 -0700770}
771
brandtrffc61182016-11-28 06:02:22 -0800772// Test that the FlexFEC field trial properly alters the output of
eladalonf1841382017-06-12 01:16:46 -0700773// WebRtcVideoEngine::codecs(), for an existing |engine_| object.
brandtrffc61182016-11-28 06:02:22 -0800774//
775// TODO(brandtr): Remove this test, when the FlexFEC field trial is gone.
eladalonf1841382017-06-12 01:16:46 -0700776TEST_F(WebRtcVideoEngineTest,
brandtrffc61182016-11-28 06:02:22 -0800777 Flexfec03SupportedAsInternalCodecBehindFieldTrial) {
778 auto is_flexfec = [](const VideoCodec& codec) {
779 if (codec.name == "flexfec-03")
780 return true;
781 return false;
782 };
783
784 // FlexFEC is not active without field trial.
brandtrffc61182016-11-28 06:02:22 -0800785 const std::vector<VideoCodec> codecs_before = engine_.codecs();
786 EXPECT_EQ(codecs_before.end(), std::find_if(codecs_before.begin(),
787 codecs_before.end(), is_flexfec));
788
789 // FlexFEC is active with field trial.
790 webrtc::test::ScopedFieldTrials override_field_trials_(
brandtr340e3fd2017-02-28 15:43:10 -0800791 "WebRTC-FlexFEC-03-Advertised/Enabled/");
brandtrffc61182016-11-28 06:02:22 -0800792 const std::vector<VideoCodec> codecs_after = engine_.codecs();
793 EXPECT_NE(codecs_after.end(),
794 std::find_if(codecs_after.begin(), codecs_after.end(), is_flexfec));
795}
796
hbosbab934b2016-01-27 01:36:03 -0800797// Test that external codecs are added to the end of the supported codec list.
eladalonf1841382017-06-12 01:16:46 -0700798TEST_F(WebRtcVideoEngineTest, ReportSupportedExternalCodecs) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200799 encoder_factory_->AddSupportedVideoCodecType("FakeExternalCodec");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000800
801 std::vector<cricket::VideoCodec> codecs(engine_.codecs());
802 ASSERT_GE(codecs.size(), 2u);
minyuef032e402017-07-17 08:45:17 -0700803 cricket::VideoCodec internal_codec = codecs.front();
804 cricket::VideoCodec external_codec = codecs.back();
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000805
minyuef032e402017-07-17 08:45:17 -0700806 // The external codec will appear last in the vector.
magjed06f3aae2017-07-14 10:36:23 -0700807 EXPECT_EQ("VP8", internal_codec.name);
minyuef032e402017-07-17 08:45:17 -0700808 EXPECT_EQ("FakeExternalCodec", external_codec.name);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000809}
810
brandtrffc61182016-11-28 06:02:22 -0800811// Test that an external codec that was added after the engine was initialized
812// does show up in the codec list after it was added.
eladalonf1841382017-06-12 01:16:46 -0700813TEST_F(WebRtcVideoEngineTest, ReportSupportedExternalCodecsWithAddedCodec) {
brandtrffc61182016-11-28 06:02:22 -0800814 // Set up external encoder factory with first codec, and initialize engine.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200815 encoder_factory_->AddSupportedVideoCodecType("FakeExternalCodec1");
brandtrffc61182016-11-28 06:02:22 -0800816
minyuef032e402017-07-17 08:45:17 -0700817 // The first external codec will appear last in the vector.
brandtrffc61182016-11-28 06:02:22 -0800818 std::vector<cricket::VideoCodec> codecs_before(engine_.codecs());
minyuef032e402017-07-17 08:45:17 -0700819 EXPECT_EQ("FakeExternalCodec1", codecs_before.back().name);
brandtrffc61182016-11-28 06:02:22 -0800820
821 // Add second codec.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200822 encoder_factory_->AddSupportedVideoCodecType("FakeExternalCodec2");
brandtrffc61182016-11-28 06:02:22 -0800823 std::vector<cricket::VideoCodec> codecs_after(engine_.codecs());
824 EXPECT_EQ(codecs_before.size() + 1, codecs_after.size());
minyuef032e402017-07-17 08:45:17 -0700825 EXPECT_EQ("FakeExternalCodec2", codecs_after.back().name);
brandtrffc61182016-11-28 06:02:22 -0800826}
827
eladalonf1841382017-06-12 01:16:46 -0700828TEST_F(WebRtcVideoEngineTest, RegisterExternalDecodersIfSupported) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200829 decoder_factory_->AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200830 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800831 parameters.codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000832
kwiberg686a8ef2016-02-26 03:00:35 -0800833 std::unique_ptr<VideoMediaChannel> channel(
magjed2475ae22017-09-12 04:42:15 -0700834 SetUpForExternalDecoderFactory(parameters.codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000835
836 EXPECT_TRUE(
837 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200838 ASSERT_EQ(1u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000839
840 // Setting codecs of the same type should not reallocate the decoder.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200841 EXPECT_TRUE(channel->SetRecvParameters(parameters));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200842 EXPECT_EQ(1, decoder_factory_->GetNumCreatedDecoders());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000843
844 // Remove stream previously added to free the external decoder instance.
845 EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200846 EXPECT_EQ(0u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000847}
848
849// Verifies that we can set up decoders that are not internally supported.
eladalonf1841382017-06-12 01:16:46 -0700850TEST_F(WebRtcVideoEngineTest, RegisterExternalH264DecoderIfSupported) {
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000851 // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We
852 // can't even query the WebRtcVideoDecoderFactory for supported codecs.
853 // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
854 // codecs.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200855 encoder_factory_->AddSupportedVideoCodecType("H264");
856 decoder_factory_->AddSupportedVideoCodecType(webrtc::kVideoCodecH264);
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000857 std::vector<cricket::VideoCodec> codecs;
magjed509e4fe2016-11-18 01:34:11 -0800858 codecs.push_back(GetEngineCodec("H264"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000859
kwiberg686a8ef2016-02-26 03:00:35 -0800860 std::unique_ptr<VideoMediaChannel> channel(
magjed2475ae22017-09-12 04:42:15 -0700861 SetUpForExternalDecoderFactory(codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000862
863 EXPECT_TRUE(
864 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200865 ASSERT_EQ(1u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000866}
867
Magnus Jedvertd4b0c052017-09-14 10:24:54 +0200868TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullFactories) {
869 std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory;
870 std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory;
871 WebRtcVideoEngine engine(std::move(encoder_factory),
872 std::move(decoder_factory));
873 EXPECT_EQ(0u, engine.codecs().size());
874}
875
876TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, EmptyFactories) {
877 // |engine| take ownership of the factories.
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -0700878 webrtc::MockVideoEncoderFactory* encoder_factory =
879 new webrtc::MockVideoEncoderFactory();
880 webrtc::MockVideoDecoderFactory* decoder_factory =
881 new webrtc::MockVideoDecoderFactory();
Magnus Jedvertd4b0c052017-09-14 10:24:54 +0200882 WebRtcVideoEngine engine(
883 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
884 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)));
885 EXPECT_CALL(*encoder_factory, GetSupportedFormats());
886 EXPECT_EQ(0u, engine.codecs().size());
887 EXPECT_CALL(*encoder_factory, Die());
888 EXPECT_CALL(*decoder_factory, Die());
889}
890
891// Test full behavior in the video engine when video codec factories of the new
892// type are injected supporting the single codec Vp8. Check the returned codecs
893// from the engine and that we will create a Vp8 encoder and decoder using the
894// new factories.
895TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) {
896 // |engine| take ownership of the factories.
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -0700897 webrtc::MockVideoEncoderFactory* encoder_factory =
898 new webrtc::MockVideoEncoderFactory();
899 webrtc::MockVideoDecoderFactory* decoder_factory =
900 new webrtc::MockVideoDecoderFactory();
Magnus Jedvertd4b0c052017-09-14 10:24:54 +0200901 WebRtcVideoEngine engine(
902 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
903 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)));
904 const webrtc::SdpVideoFormat vp8_format("VP8");
905 const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
906 EXPECT_CALL(*encoder_factory, GetSupportedFormats())
907 .WillRepeatedly(testing::Return(supported_formats));
908
909 // Verify the codecs from the engine.
910 const std::vector<VideoCodec> engine_codecs = engine.codecs();
911 // Verify an RTX codec has been added correctly.
912 EXPECT_EQ(2u, engine_codecs.size());
913 EXPECT_EQ("VP8", engine_codecs.at(0).name);
914 EXPECT_EQ("rtx", engine_codecs.at(1).name);
915 int associated_payload_type;
916 EXPECT_TRUE(engine_codecs.at(1).GetParam(
917 cricket::kCodecParamAssociatedPayloadType, &associated_payload_type));
918 EXPECT_EQ(engine_codecs.at(0).id, associated_payload_type);
919 // Verify default parameters has been added to the VP8 codec.
920 VerifyCodecHasDefaultFeedbackParams(engine_codecs.at(0));
921
922 // Mock encoder creation. |engine| take ownership of the encoder.
923 webrtc::VideoEncoderFactory::CodecInfo codec_info;
924 codec_info.is_hardware_accelerated = false;
925 codec_info.has_internal_source = false;
926 const webrtc::SdpVideoFormat format("VP8");
927 EXPECT_CALL(*encoder_factory, QueryVideoEncoder(format))
928 .WillRepeatedly(testing::Return(codec_info));
929 FakeWebRtcVideoEncoder* const encoder = new FakeWebRtcVideoEncoder();
930 EXPECT_CALL(*encoder_factory, CreateVideoEncoderProxy(format))
931 .WillOnce(testing::Return(encoder));
932
933 // Mock decoder creation. |engine| take ownership of the decoder.
934 FakeWebRtcVideoDecoder* const decoder = new FakeWebRtcVideoDecoder();
935 EXPECT_CALL(*decoder_factory, CreateVideoDecoderProxy(format))
936 .WillOnce(testing::Return(decoder));
937
938 // Create a call.
939 webrtc::RtcEventLogNullImpl event_log;
940 std::unique_ptr<webrtc::Call> call(
941 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
942
943 // Create send channel.
944 const int send_ssrc = 123;
945 std::unique_ptr<VideoMediaChannel> send_channel(
946 engine.CreateChannel(call.get(), GetMediaConfig(), VideoOptions()));
947 cricket::VideoSendParameters send_parameters;
948 send_parameters.codecs.push_back(engine_codecs.at(0));
949 EXPECT_TRUE(send_channel->SetSendParameters(send_parameters));
950 send_channel->OnReadyToSend(true);
951 EXPECT_TRUE(
952 send_channel->AddSendStream(StreamParams::CreateLegacy(send_ssrc)));
953 EXPECT_TRUE(send_channel->SetSend(true));
954
955 // Create recv channel.
956 const int recv_ssrc = 321;
957 std::unique_ptr<VideoMediaChannel> recv_channel(
958 engine.CreateChannel(call.get(), GetMediaConfig(), VideoOptions()));
959 cricket::VideoRecvParameters recv_parameters;
960 recv_parameters.codecs.push_back(engine_codecs.at(0));
961 EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
962 EXPECT_TRUE(recv_channel->AddRecvStream(
963 cricket::StreamParams::CreateLegacy(recv_ssrc)));
964
965 // Remove streams previously added to free the encoder and decoder instance.
966 EXPECT_CALL(*encoder_factory, Die());
967 EXPECT_CALL(*decoder_factory, Die());
968 EXPECT_TRUE(send_channel->RemoveSendStream(send_ssrc));
969 EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
970}
971
eladalonf1841382017-06-12 01:16:46 -0700972class WebRtcVideoChannelBaseTest
973 : public VideoMediaChannelTest<WebRtcVideoEngine, WebRtcVideoChannel> {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000974 protected:
eladalonf1841382017-06-12 01:16:46 -0700975 typedef VideoMediaChannelTest<WebRtcVideoEngine, WebRtcVideoChannel> Base;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000976
magjed509e4fe2016-11-18 01:34:11 -0800977 cricket::VideoCodec GetEngineCodec(const std::string& name) {
978 for (const cricket::VideoCodec& engine_codec : engine_.codecs()) {
979 if (CodecNamesEq(name, engine_codec.name))
980 return engine_codec;
981 }
982 // This point should never be reached.
983 ADD_FAILURE() << "Unrecognized codec name: " << name;
984 return cricket::VideoCodec();
985 }
986
987 cricket::VideoCodec DefaultCodec() override { return GetEngineCodec("VP8"); }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000988};
989
sakal1fd95952016-06-22 00:46:15 -0700990// Verifies that id given in stream params is passed to the decoder factory.
eladalonf1841382017-06-12 01:16:46 -0700991TEST_F(WebRtcVideoEngineTest, StreamParamsIdPassedToDecoderFactory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200992 decoder_factory_->AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
sakal1fd95952016-06-22 00:46:15 -0700993 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800994 parameters.codecs.push_back(GetEngineCodec("VP8"));
sakal1fd95952016-06-22 00:46:15 -0700995
996 std::unique_ptr<VideoMediaChannel> channel(
magjed2475ae22017-09-12 04:42:15 -0700997 SetUpForExternalDecoderFactory(parameters.codecs));
sakal1fd95952016-06-22 00:46:15 -0700998
999 StreamParams sp = cricket::StreamParams::CreateLegacy(kSsrc);
1000 sp.id = "FakeStreamParamsId";
1001 EXPECT_TRUE(channel->AddRecvStream(sp));
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001002 EXPECT_EQ(1u, decoder_factory_->decoders().size());
sakal1fd95952016-06-22 00:46:15 -07001003
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001004 std::vector<cricket::VideoDecoderParams> params = decoder_factory_->params();
sakal1fd95952016-06-22 00:46:15 -07001005 ASSERT_EQ(1u, params.size());
1006 EXPECT_EQ(sp.id, params[0].receive_stream_id);
1007}
1008
eladalonf1841382017-06-12 01:16:46 -07001009TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001010 encoder_factory_->AddSupportedVideoCodecType("VP8");
sprangf24a0642017-02-28 13:23:26 -08001011 std::unique_ptr<FakeCall> fake_call(
1012 new FakeCall(webrtc::Call::Config(&event_log_)));
magjed2475ae22017-09-12 04:42:15 -07001013 std::unique_ptr<VideoMediaChannel> channel(SetUpForExternalEncoderFactory());
sprangf24a0642017-02-28 13:23:26 -08001014 ASSERT_TRUE(
1015 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1016 cricket::VideoCodec codec = GetEngineCodec("VP8");
1017 cricket::VideoSendParameters parameters;
1018 parameters.codecs.push_back(codec);
1019 channel->OnReadyToSend(true);
1020 channel->SetSend(true);
1021 ASSERT_TRUE(channel->SetSendParameters(parameters));
1022
1023 cricket::FakeVideoCapturer capturer;
1024 VideoOptions options;
1025 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, &options, &capturer));
1026
1027 EXPECT_EQ(cricket::CS_RUNNING,
1028 capturer.Start(capturer.GetSupportedFormats()->front()));
1029 EXPECT_TRUE(capturer.CaptureFrame());
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001030 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
sprangf24a0642017-02-28 13:23:26 -08001031 EXPECT_EQ(webrtc::kRealtimeVideo,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001032 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001033
1034 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, &options, &capturer));
1035 EXPECT_TRUE(capturer.CaptureFrame());
1036 // No change in content type, keep current encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001037 EXPECT_EQ(1, encoder_factory_->GetNumCreatedEncoders());
sprangf24a0642017-02-28 13:23:26 -08001038
1039 options.is_screencast.emplace(true);
1040 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, &options, &capturer));
1041 EXPECT_TRUE(capturer.CaptureFrame());
1042 // Change to screen content, recreate encoder. For the simulcast encoder
1043 // adapter case, this will result in two calls since InitEncode triggers a
1044 // a new instance.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001045 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
sprangf24a0642017-02-28 13:23:26 -08001046 EXPECT_EQ(webrtc::kScreensharing,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001047 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001048
1049 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, &options, &capturer));
1050 EXPECT_TRUE(capturer.CaptureFrame());
1051 // Still screen content, no need to update encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001052 EXPECT_EQ(2, encoder_factory_->GetNumCreatedEncoders());
sprangf24a0642017-02-28 13:23:26 -08001053
1054 options.is_screencast.emplace(false);
1055 options.video_noise_reduction.emplace(false);
1056 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, &options, &capturer));
1057 // Change back to regular video content, update encoder. Also change
1058 // a non |is_screencast| option just to verify it doesn't affect recreation.
1059 EXPECT_TRUE(capturer.CaptureFrame());
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001060 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(3));
sprangf24a0642017-02-28 13:23:26 -08001061 EXPECT_EQ(webrtc::kRealtimeVideo,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001062 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001063
1064 // Remove stream previously added to free the external encoder instance.
1065 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001066 EXPECT_EQ(0u, encoder_factory_->encoders().size());
sprangf24a0642017-02-28 13:23:26 -08001067}
1068
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001069#define WEBRTC_BASE_TEST(test) \
eladalonf1841382017-06-12 01:16:46 -07001070 TEST_F(WebRtcVideoChannelBaseTest, test) { Base::test(); }
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001071
1072#define WEBRTC_DISABLED_BASE_TEST(test) \
eladalonf1841382017-06-12 01:16:46 -07001073 TEST_F(WebRtcVideoChannelBaseTest, DISABLED_##test) { Base::test(); }
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001074
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001075WEBRTC_BASE_TEST(SetSend);
1076WEBRTC_BASE_TEST(SetSendWithoutCodecs);
1077WEBRTC_BASE_TEST(SetSendSetsTransportBufferSizes);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001078
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001079WEBRTC_BASE_TEST(GetStats);
1080WEBRTC_BASE_TEST(GetStatsMultipleRecvStreams);
1081WEBRTC_BASE_TEST(GetStatsMultipleSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001082
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001083WEBRTC_BASE_TEST(SetSendBandwidth);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001084
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001085WEBRTC_BASE_TEST(SetSendSsrc);
1086WEBRTC_BASE_TEST(SetSendSsrcAfterSetCodecs);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001087
nisse08582ff2016-02-04 01:24:52 -08001088WEBRTC_BASE_TEST(SetSink);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001089
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001090WEBRTC_BASE_TEST(AddRemoveSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001091
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001092WEBRTC_BASE_TEST(SimulateConference);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001093
Alejandro Luebs947c02d2016-06-15 15:39:46 -07001094WEBRTC_DISABLED_BASE_TEST(AddRemoveCapturer);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001095
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001096WEBRTC_BASE_TEST(RemoveCapturerWithoutAdd);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001097
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001098WEBRTC_BASE_TEST(AddRemoveCapturerMultipleSources);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001099
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001100WEBRTC_BASE_TEST(RejectEmptyStreamParams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001101
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +00001102WEBRTC_BASE_TEST(MultipleSendStreams);
1103
eladalonf1841382017-06-12 01:16:46 -07001104TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Vga) {
magjed509e4fe2016-11-18 01:34:11 -08001105 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00001106}
1107
eladalonf1841382017-06-12 01:16:46 -07001108TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Qvga) {
magjed509e4fe2016-11-18 01:34:11 -08001109 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00001110}
1111
eladalonf1841382017-06-12 01:16:46 -07001112TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8SvcQqvga) {
magjed509e4fe2016-11-18 01:34:11 -08001113 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00001114}
1115
eladalonf1841382017-06-12 01:16:46 -07001116TEST_F(WebRtcVideoChannelBaseTest, TwoStreamsSendAndReceive) {
Peter Boströmd1f584b2016-04-20 16:31:53 +02001117 // Set a high bitrate to not be downscaled by VP8 due to low initial start
1118 // bitrates. This currently happens at <250k, and two streams sharing 300k
1119 // initially will use QVGA instead of VGA.
1120 // TODO(pbos): Set up the quality scaler so that both senders reliably start
1121 // at QVGA, then verify that instead.
magjed509e4fe2016-11-18 01:34:11 -08001122 cricket::VideoCodec codec = GetEngineCodec("VP8");
Peter Boströmd1f584b2016-04-20 16:31:53 +02001123 codec.params[kCodecParamStartBitrate] = "1000000";
1124 Base::TwoStreamsSendAndReceive(codec);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001125}
1126
eladalonf1841382017-06-12 01:16:46 -07001127class WebRtcVideoChannelTest : public WebRtcVideoEngineTest {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001128 public:
eladalonf1841382017-06-12 01:16:46 -07001129 WebRtcVideoChannelTest() : WebRtcVideoChannelTest("") {}
1130 explicit WebRtcVideoChannelTest(const char* field_trials)
1131 : WebRtcVideoEngineTest(field_trials), last_ssrc_(0) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001132 void SetUp() override {
skvlad11a9cbf2016-10-07 11:53:05 -07001133 fake_call_.reset(new FakeCall(webrtc::Call::Config(&event_log_)));
kthelgason2bc68642017-02-07 07:02:22 -08001134 channel_.reset(engine_.CreateChannel(fake_call_.get(), GetMediaConfig(),
1135 VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08001136 channel_->OnReadyToSend(true);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001137 last_ssrc_ = 123;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001138 send_parameters_.codecs = engine_.codecs();
1139 recv_parameters_.codecs = engine_.codecs();
1140 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001141 }
1142
1143 protected:
1144 FakeVideoSendStream* AddSendStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001145 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001146 }
1147
1148 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001149 size_t num_streams = fake_call_->GetVideoSendStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001150 EXPECT_TRUE(channel_->AddSendStream(sp));
1151 std::vector<FakeVideoSendStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001152 fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001153 EXPECT_EQ(num_streams + 1, streams.size());
1154 return streams[streams.size() - 1];
1155 }
1156
1157 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001158 return fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001159 }
1160
1161 FakeVideoReceiveStream* AddRecvStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001162 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001163 }
1164
1165 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001166 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001167 EXPECT_TRUE(channel_->AddRecvStream(sp));
1168 std::vector<FakeVideoReceiveStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001169 fake_call_->GetVideoReceiveStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001170 EXPECT_EQ(num_streams + 1, streams.size());
1171 return streams[streams.size() - 1];
1172 }
1173
pbos@webrtc.org00873182014-11-25 14:03:34 +00001174 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
1175 int expected_min_bitrate_bps,
1176 const char* start_bitrate_kbps,
1177 int expected_start_bitrate_bps,
1178 const char* max_bitrate_kbps,
1179 int expected_max_bitrate_bps) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001180 auto& codecs = send_parameters_.codecs;
1181 codecs.clear();
magjed509e4fe2016-11-18 01:34:11 -08001182 codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org00873182014-11-25 14:03:34 +00001183 codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps;
1184 codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps;
1185 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001186 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001187
pbos@webrtc.org00873182014-11-25 14:03:34 +00001188 EXPECT_EQ(expected_min_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +01001189 fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00001190 EXPECT_EQ(expected_start_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +01001191 fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00001192 EXPECT_EQ(expected_max_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +01001193 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001194 }
1195
isheriff6f8d6862016-05-26 11:24:55 -07001196 void TestSetSendRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001197 // Enable extension.
1198 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001199 cricket::VideoSendParameters parameters = send_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07001200 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001201 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001202 FakeVideoSendStream* send_stream =
1203 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1204
1205 // Verify the send extension id.
1206 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1207 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001208 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001209 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001210 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001211 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
1212 // receivers.
1213 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
1214 ->GetConfig()
1215 .rtp.extensions.empty());
1216
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001217 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001218 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001219 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1220 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001221 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
1222
1223 // Verify that adding receive RTP header extensions adds them for existing
1224 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001225 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001226 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001227 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1228 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001229 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001230 }
1231
isheriff6f8d6862016-05-26 11:24:55 -07001232 void TestSetRecvRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001233 // Enable extension.
1234 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001235 cricket::VideoRecvParameters parameters = recv_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07001236 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001237 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001238
1239 FakeVideoReceiveStream* recv_stream =
1240 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1241
1242 // Verify the recv extension id.
1243 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1244 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001245 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001246 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001247 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001248
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001249 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
1250 // senders.
1251 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
1252 ->GetConfig()
1253 .rtp.extensions.empty());
1254
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001255 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001256 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001257 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
1258 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001259 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
1260
1261 // Verify that adding receive RTP header extensions adds them for existing
1262 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001263 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001264 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001265 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1266 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001267 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001268 }
1269
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001270 void TestExtensionFilter(const std::vector<std::string>& extensions,
1271 const std::string& expected_extension) {
1272 cricket::VideoSendParameters parameters = send_parameters_;
1273 int expected_id = -1;
1274 int id = 1;
1275 for (const std::string& extension : extensions) {
1276 if (extension == expected_extension)
1277 expected_id = id;
isheriff6f8d6862016-05-26 11:24:55 -07001278 parameters.extensions.push_back(RtpExtension(extension, id++));
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001279 }
1280 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1281 FakeVideoSendStream* send_stream =
1282 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1283
1284 // Verify that only one of them has been set, and that it is the one with
1285 // highest priority (transport sequence number).
1286 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1287 EXPECT_EQ(expected_id, send_stream->GetConfig().rtp.extensions[0].id);
1288 EXPECT_EQ(expected_extension,
isheriff6f8d6862016-05-26 11:24:55 -07001289 send_stream->GetConfig().rtp.extensions[0].uri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001290 }
1291
asapersson3c81a1a2017-06-14 05:52:21 -07001292 void TestDegradationPreference(bool resolution_scaling_enabled,
1293 bool fps_scaling_enabled);
1294
Erik Språngefbde372015-04-29 16:21:28 +02001295 void TestCpuAdaptation(bool enable_overuse, bool is_screenshare);
Peter Boström3548dd22015-05-22 18:48:36 +02001296 void TestReceiverLocalSsrcConfiguration(bool receiver_first);
magjed509e4fe2016-11-18 01:34:11 -08001297 void TestReceiveUnsignaledSsrcPacket(uint8_t payload_type,
1298 bool expect_created_receive_stream);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001299
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001300 FakeVideoSendStream* SetDenoisingOption(
nisse05103312016-03-16 02:22:50 -07001301 uint32_t ssrc,
nisse0db023a2016-03-01 04:29:59 -08001302 cricket::FakeVideoCapturer* capturer,
1303 bool enabled) {
nisse05103312016-03-16 02:22:50 -07001304 cricket::VideoOptions options;
1305 options.video_noise_reduction = rtc::Optional<bool>(enabled);
deadbeef5a4a75a2016-06-02 16:23:38 -07001306 EXPECT_TRUE(channel_->SetVideoSend(ssrc, true, &options, capturer));
nisse0db023a2016-03-01 04:29:59 -08001307 // Options only take effect on the next frame.
1308 EXPECT_TRUE(capturer->CaptureFrame());
1309
Erik Språng143cec12015-04-28 10:01:41 +02001310 return fake_call_->GetVideoSendStreams().back();
1311 }
1312
Peter Boström2feafdb2015-09-09 14:32:14 +02001313 FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) {
1314 const int kRtxSsrcOffset = 0xDEADBEEF;
Erik Språng143cec12015-04-28 10:01:41 +02001315 last_ssrc_ += 3;
Peter Boström2feafdb2015-09-09 14:32:14 +02001316 std::vector<uint32_t> ssrcs;
1317 std::vector<uint32_t> rtx_ssrcs;
1318 uint32_t num_streams = enabled ? 3 : 1;
1319 for (uint32_t i = 0; i < num_streams; ++i) {
1320 uint32_t ssrc = last_ssrc_ + i;
1321 ssrcs.push_back(ssrc);
1322 if (with_rtx) {
1323 rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset);
1324 }
Erik Språng143cec12015-04-28 10:01:41 +02001325 }
Peter Boström2feafdb2015-09-09 14:32:14 +02001326 if (with_rtx) {
1327 return AddSendStream(
1328 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1329 }
1330 return AddSendStream(CreateSimStreamParams("cname", ssrcs));
Erik Språng143cec12015-04-28 10:01:41 +02001331 }
1332
perkjfa10b552016-10-02 23:45:26 -07001333 int GetMaxEncoderBitrate() {
skvladdc1c62c2016-03-16 19:07:43 -07001334 std::vector<FakeVideoSendStream*> streams =
1335 fake_call_->GetVideoSendStreams();
perkjfa10b552016-10-02 23:45:26 -07001336 EXPECT_EQ(1u, streams.size());
skvladdc1c62c2016-03-16 19:07:43 -07001337 FakeVideoSendStream* stream = streams[streams.size() - 1];
perkjfa10b552016-10-02 23:45:26 -07001338 EXPECT_EQ(1, stream->GetEncoderConfig().number_of_streams);
1339 return stream->GetVideoStreams()[0].max_bitrate_bps;
skvladdc1c62c2016-03-16 19:07:43 -07001340 }
1341
perkjfa10b552016-10-02 23:45:26 -07001342 void SetAndExpectMaxBitrate(int global_max,
skvladdc1c62c2016-03-16 19:07:43 -07001343 int stream_max,
1344 int expected_encoder_bitrate) {
1345 VideoSendParameters limited_send_params = send_parameters_;
1346 limited_send_params.max_bandwidth_bps = global_max;
1347 EXPECT_TRUE(channel_->SetSendParameters(limited_send_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001348 webrtc::RtpParameters parameters =
1349 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07001350 EXPECT_EQ(1UL, parameters.encodings.size());
deadbeefe702b302017-02-04 12:09:01 -08001351 parameters.encodings[0].max_bitrate_bps = rtc::Optional<int>(stream_max);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001352 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07001353 // Read back the parameteres and verify they have the correct value
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001354 parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07001355 EXPECT_EQ(1UL, parameters.encodings.size());
deadbeefe702b302017-02-04 12:09:01 -08001356 EXPECT_EQ(rtc::Optional<int>(stream_max),
1357 parameters.encodings[0].max_bitrate_bps);
skvladdc1c62c2016-03-16 19:07:43 -07001358 // Verify that the new value propagated down to the encoder
perkjfa10b552016-10-02 23:45:26 -07001359 EXPECT_EQ(expected_encoder_bitrate, GetMaxEncoderBitrate());
skvladdc1c62c2016-03-16 19:07:43 -07001360 }
1361
kwiberg686a8ef2016-02-26 03:00:35 -08001362 std::unique_ptr<FakeCall> fake_call_;
1363 std::unique_ptr<VideoMediaChannel> channel_;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001364 cricket::VideoSendParameters send_parameters_;
1365 cricket::VideoRecvParameters recv_parameters_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001366 uint32_t last_ssrc_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001367};
1368
eladalonf1841382017-06-12 01:16:46 -07001369TEST_F(WebRtcVideoChannelTest, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02001370 const uint32_t kVideoSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07001371 const std::string kSyncLabel = "AvSyncLabel";
1372
1373 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc);
1374 sp.sync_label = kSyncLabel;
1375 EXPECT_TRUE(channel_->AddRecvStream(sp));
1376
1377 EXPECT_EQ(1, fake_call_->GetVideoReceiveStreams().size());
1378 EXPECT_EQ(kSyncLabel,
1379 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group)
1380 << "SyncGroup should be set based on sync_label";
1381}
1382
eladalonf1841382017-06-12 01:16:46 -07001383TEST_F(WebRtcVideoChannelTest, RecvStreamWithSimAndRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001384 cricket::VideoSendParameters parameters;
1385 parameters.codecs = engine_.codecs();
1386 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001387 EXPECT_TRUE(channel_->SetSend(true));
nisse4b4dc862016-02-17 05:25:36 -08001388 parameters.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001389 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001390
1391 // Send side.
Peter Boström0c4e06b2015-10-07 12:23:21 +02001392 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
1393 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001394 FakeVideoSendStream* send_stream = AddSendStream(
1395 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1396
1397 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
1398 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
1399 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
1400
1401 // Receiver side.
1402 FakeVideoReceiveStream* recv_stream = AddRecvStream(
1403 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
nisse26e3abb2017-08-25 04:44:25 -07001404 EXPECT_FALSE(
1405 recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
nisseca5706d2017-09-11 02:32:16 -07001406 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
Peter Boströmd8b01092016-05-12 16:44:36 +02001407 << "RTX should be mapped for all decoders/payload types.";
nisseca5706d2017-09-11 02:32:16 -07001408 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
1409 GetEngineCodec("red").id))
1410 << "RTX should be mapped for the RED payload type";
1411
brandtr14742122017-01-27 04:53:07 -08001412 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001413}
1414
eladalonf1841382017-06-12 01:16:46 -07001415TEST_F(WebRtcVideoChannelTest, RecvStreamWithRtx) {
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001416 // Setup one channel with an associated RTX stream.
1417 cricket::StreamParams params =
1418 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
1419 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
1420 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
brandtr14742122017-01-27 04:53:07 -08001421 EXPECT_EQ(kRtxSsrcs1[0], recv_stream->GetConfig().rtp.rtx_ssrc);
nisseca5706d2017-09-11 02:32:16 -07001422
1423 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
1424 << "RTX should be mapped for all decoders/payload types.";
1425 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
1426 GetEngineCodec("red").id))
1427 << "RTX should be mapped for the RED payload type";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001428}
1429
eladalonf1841382017-06-12 01:16:46 -07001430TEST_F(WebRtcVideoChannelTest, RecvStreamNoRtx) {
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001431 // Setup one channel without an associated RTX stream.
1432 cricket::StreamParams params =
1433 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
1434 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
brandtr14742122017-01-27 04:53:07 -08001435 ASSERT_EQ(0U, recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001436}
1437
eladalonf1841382017-06-12 01:16:46 -07001438TEST_F(WebRtcVideoChannelTest, NoHeaderExtesionsByDefault) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001439 FakeVideoSendStream* send_stream =
1440 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
1441 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
1442
1443 FakeVideoReceiveStream* recv_stream =
1444 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
1445 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001446}
1447
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001448// Test support for RTP timestamp offset header extension.
eladalonf1841382017-06-12 01:16:46 -07001449TEST_F(WebRtcVideoChannelTest, SendRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001450 TestSetSendRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001451}
isheriff6f8d6862016-05-26 11:24:55 -07001452
eladalonf1841382017-06-12 01:16:46 -07001453TEST_F(WebRtcVideoChannelTest, RecvRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001454 TestSetRecvRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001455}
1456
1457// Test support for absolute send time header extension.
eladalonf1841382017-06-12 01:16:46 -07001458TEST_F(WebRtcVideoChannelTest, SendAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001459 TestSetSendRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001460}
isheriff6f8d6862016-05-26 11:24:55 -07001461
eladalonf1841382017-06-12 01:16:46 -07001462TEST_F(WebRtcVideoChannelTest, RecvAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001463 TestSetRecvRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001464}
1465
eladalonf1841382017-06-12 01:16:46 -07001466TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksTransportSeqNum) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001467 // Enable three redundant extensions.
1468 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07001469 extensions.push_back(RtpExtension::kAbsSendTimeUri);
1470 extensions.push_back(RtpExtension::kTimestampOffsetUri);
1471 extensions.push_back(RtpExtension::kTransportSequenceNumberUri);
1472 TestExtensionFilter(extensions, RtpExtension::kTransportSequenceNumberUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001473}
1474
eladalonf1841382017-06-12 01:16:46 -07001475TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksAbsSendTime) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001476 // Enable two redundant extensions.
1477 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07001478 extensions.push_back(RtpExtension::kAbsSendTimeUri);
1479 extensions.push_back(RtpExtension::kTimestampOffsetUri);
1480 TestExtensionFilter(extensions, RtpExtension::kAbsSendTimeUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001481}
1482
stefanc1aeaf02015-10-15 07:26:07 -07001483// Test support for transport sequence number header extension.
eladalonf1841382017-06-12 01:16:46 -07001484TEST_F(WebRtcVideoChannelTest, SendTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001485 TestSetSendRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07001486}
eladalonf1841382017-06-12 01:16:46 -07001487TEST_F(WebRtcVideoChannelTest, RecvTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001488 TestSetRecvRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07001489}
1490
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001491// Test support for video rotation header extension.
eladalonf1841382017-06-12 01:16:46 -07001492TEST_F(WebRtcVideoChannelTest, SendVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001493 TestSetSendRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001494}
eladalonf1841382017-06-12 01:16:46 -07001495TEST_F(WebRtcVideoChannelTest, RecvVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001496 TestSetRecvRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001497}
1498
eladalonf1841382017-06-12 01:16:46 -07001499TEST_F(WebRtcVideoChannelTest, IdenticalSendExtensionsDoesntRecreateStream) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001500 const int kAbsSendTimeId = 1;
1501 const int kVideoRotationId = 2;
isheriff6f8d6862016-05-26 11:24:55 -07001502 send_parameters_.extensions.push_back(
1503 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
1504 send_parameters_.extensions.push_back(
1505 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001506
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001507 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001508 FakeVideoSendStream* send_stream =
1509 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1510
1511 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001512 ASSERT_EQ(2u, send_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001513
1514 // Setting the same extensions (even if in different order) shouldn't
1515 // reallocate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001516 std::reverse(send_parameters_.extensions.begin(),
1517 send_parameters_.extensions.end());
1518 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001519
1520 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1521
1522 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001523 send_parameters_.extensions.resize(1);
1524 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001525
1526 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
1527}
1528
eladalonf1841382017-06-12 01:16:46 -07001529TEST_F(WebRtcVideoChannelTest, IdenticalRecvExtensionsDoesntRecreateStream) {
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001530 const int kTOffsetId = 1;
1531 const int kAbsSendTimeId = 2;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001532 const int kVideoRotationId = 3;
isheriff6f8d6862016-05-26 11:24:55 -07001533 recv_parameters_.extensions.push_back(
1534 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
1535 recv_parameters_.extensions.push_back(
1536 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
1537 recv_parameters_.extensions.push_back(
1538 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001539
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001540 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Peter Boström54be3e02015-05-25 15:04:24 +02001541 FakeVideoReceiveStream* recv_stream =
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001542 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1543
1544 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Peter Boström54be3e02015-05-25 15:04:24 +02001545 ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001546
1547 // Setting the same extensions (even if in different order) shouldn't
1548 // reallocate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001549 std::reverse(recv_parameters_.extensions.begin(),
1550 recv_parameters_.extensions.end());
1551 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001552
1553 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
1554
1555 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001556 recv_parameters_.extensions.resize(1);
1557 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001558
1559 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
1560}
1561
eladalonf1841382017-06-12 01:16:46 -07001562TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001563 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001564 const int kUnsupportedId = 1;
1565 const int kTOffsetId = 2;
1566
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001567 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001568 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001569 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001570 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001571 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001572 FakeVideoSendStream* send_stream =
1573 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1574
1575 // Only timestamp offset extension is set to send stream,
1576 // unsupported rtp extension is ignored.
1577 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07001578 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
1579 send_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001580}
1581
eladalonf1841382017-06-12 01:16:46 -07001582TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001583 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001584 const int kUnsupportedId = 1;
1585 const int kTOffsetId = 2;
1586
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001587 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001588 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001589 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001590 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001591 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001592 FakeVideoReceiveStream* recv_stream =
1593 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1594
1595 // Only timestamp offset extension is set to receive stream,
1596 // unsupported rtp extension is ignored.
1597 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07001598 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
1599 recv_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001600}
1601
eladalonf1841382017-06-12 01:16:46 -07001602TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02001603 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00001604 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07001605 send_parameters_.extensions.push_back(
1606 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001607 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001608 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1609 }
1610}
1611
eladalonf1841382017-06-12 01:16:46 -07001612TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02001613 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00001614 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07001615 recv_parameters_.extensions.push_back(
1616 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001617 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001618 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1619 }
1620}
1621
eladalonf1841382017-06-12 01:16:46 -07001622TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001623 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001624 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001625 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001626 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001627 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001628 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001629
1630 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001631 send_parameters_.extensions.clear();
1632 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001633 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001634 send_parameters_.extensions.push_back(send_parameters_.extensions.back());
1635 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001636}
1637
eladalonf1841382017-06-12 01:16:46 -07001638TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001639 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001640 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001641 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001642 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001643 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001644 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001645
1646 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001647 recv_parameters_.extensions.clear();
1648 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001649 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001650 recv_parameters_.extensions.push_back(recv_parameters_.extensions.back());
1651 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001652}
1653
eladalonf1841382017-06-12 01:16:46 -07001654TEST_F(WebRtcVideoChannelTest, AddRecvStreamOnlyUsesOneReceiveStream) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001655 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001656 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001657}
1658
eladalonf1841382017-06-12 01:16:46 -07001659TEST_F(WebRtcVideoChannelTest, RtcpIsCompoundByDefault) {
Peter Boströmd7da1202015-06-05 14:09:38 +02001660 FakeVideoReceiveStream* stream = AddRecvStream();
pbosda903ea2015-10-02 02:36:56 -07001661 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream->GetConfig().rtp.rtcp_mode);
Peter Boströmd7da1202015-06-05 14:09:38 +02001662}
1663
eladalonf1841382017-06-12 01:16:46 -07001664TEST_F(WebRtcVideoChannelTest, RembIsEnabledByDefault) {
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001665 FakeVideoReceiveStream* stream = AddRecvStream();
1666 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001667}
1668
eladalonf1841382017-06-12 01:16:46 -07001669TEST_F(WebRtcVideoChannelTest, TransportCcIsEnabledByDefault) {
stefan43edf0f2015-11-20 18:05:48 -08001670 FakeVideoReceiveStream* stream = AddRecvStream();
1671 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1672}
1673
eladalonf1841382017-06-12 01:16:46 -07001674TEST_F(WebRtcVideoChannelTest, RembCanBeEnabledAndDisabled) {
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001675 FakeVideoReceiveStream* stream = AddRecvStream();
1676 EXPECT_TRUE(stream->GetConfig().rtp.remb);
1677
Peter Boström126c03e2015-05-11 12:48:12 +02001678 // Verify that REMB is turned off when send(!) codecs without REMB are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001679 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001680 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001681 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1682 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001683 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001684 EXPECT_FALSE(stream->GetConfig().rtp.remb);
1685
1686 // Verify that REMB is turned on when setting default codecs since the
1687 // default codecs have REMB enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001688 parameters.codecs = engine_.codecs();
1689 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001690 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001691 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001692}
1693
eladalonf1841382017-06-12 01:16:46 -07001694TEST_F(WebRtcVideoChannelTest, TransportCcCanBeEnabledAndDisabled) {
stefan43edf0f2015-11-20 18:05:48 -08001695 FakeVideoReceiveStream* stream = AddRecvStream();
1696 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1697
1698 // Verify that transport cc feedback is turned off when send(!) codecs without
1699 // transport cc feedback are set.
1700 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001701 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
stefan43edf0f2015-11-20 18:05:48 -08001702 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1703 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1704 stream = fake_call_->GetVideoReceiveStreams()[0];
1705 EXPECT_FALSE(stream->GetConfig().rtp.transport_cc);
1706
1707 // Verify that transport cc feedback is turned on when setting default codecs
1708 // since the default codecs have transport cc feedback enabled.
1709 parameters.codecs = engine_.codecs();
1710 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1711 stream = fake_call_->GetVideoReceiveStreams()[0];
1712 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1713}
1714
eladalonf1841382017-06-12 01:16:46 -07001715TEST_F(WebRtcVideoChannelTest, NackIsEnabledByDefault) {
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001716 VerifyCodecHasDefaultFeedbackParams(default_codec_);
1717
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001718 cricket::VideoSendParameters parameters;
1719 parameters.codecs = engine_.codecs();
1720 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org19864742014-05-30 07:35:47 +00001721 EXPECT_TRUE(channel_->SetSend(true));
1722
1723 // Send side.
1724 FakeVideoSendStream* send_stream =
1725 AddSendStream(cricket::StreamParams::CreateLegacy(1));
1726 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1727
1728 // Receiver side.
1729 FakeVideoReceiveStream* recv_stream =
1730 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
1731 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1732
1733 // Nack history size should match between sender and receiver.
1734 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
1735 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001736}
1737
eladalonf1841382017-06-12 01:16:46 -07001738TEST_F(WebRtcVideoChannelTest, NackCanBeEnabledAndDisabled) {
Peter Boström67c9df72015-05-11 14:34:58 +02001739 FakeVideoSendStream* send_stream = AddSendStream();
Peter Boström3548dd22015-05-22 18:48:36 +02001740 FakeVideoReceiveStream* recv_stream = AddRecvStream();
Peter Boström67c9df72015-05-11 14:34:58 +02001741
1742 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1743 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1744
1745 // Verify that NACK is turned off when send(!) codecs without NACK are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001746 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001747 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001748 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1749 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02001750 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1751 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
1752 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001753 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
1754
Peter Boström67c9df72015-05-11 14:34:58 +02001755 // Verify that NACK is turned on when setting default codecs since the
1756 // default codecs have NACK enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001757 parameters.codecs = engine_.codecs();
1758 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02001759 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1760 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1761 send_stream = fake_call_->GetVideoSendStreams()[0];
1762 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001763}
1764
Peter Boströme7ba0862016-03-12 00:02:28 +01001765// This test verifies that new frame sizes reconfigures encoders even though not
1766// (yet) sending. The purpose of this is to permit encoding as quickly as
1767// possible once we start sending. Likely the frames being input are from the
1768// same source that will be sent later, which just means that we're ready
1769// earlier.
eladalonf1841382017-06-12 01:16:46 -07001770TEST_F(WebRtcVideoChannelTest, ReconfiguresEncodersWhenNotSending) {
Peter Boströme7ba0862016-03-12 00:02:28 +01001771 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001772 parameters.codecs.push_back(GetEngineCodec("VP8"));
Peter Boströme7ba0862016-03-12 00:02:28 +01001773 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1774 channel_->SetSend(false);
1775
1776 FakeVideoSendStream* stream = AddSendStream();
1777
perkjfa10b552016-10-02 23:45:26 -07001778 // No frames entered.
Peter Boströme7ba0862016-03-12 00:02:28 +01001779 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07001780 EXPECT_EQ(0u, streams[0].width);
1781 EXPECT_EQ(0u, streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01001782
1783 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07001784 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
perkj26752742016-10-24 01:21:16 -07001785 VideoFormat capture_format = capturer.GetSupportedFormats()->front();
1786 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format));
Peter Boströme7ba0862016-03-12 00:02:28 +01001787 EXPECT_TRUE(capturer.CaptureFrame());
1788
1789 // Frame entered, should be reconfigured to new dimensions.
1790 streams = stream->GetVideoStreams();
perkj26752742016-10-24 01:21:16 -07001791 EXPECT_EQ(capture_format.width, streams[0].width);
1792 EXPECT_EQ(capture_format.height, streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01001793
deadbeef5a4a75a2016-06-02 16:23:38 -07001794 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boströme7ba0862016-03-12 00:02:28 +01001795}
1796
eladalonf1841382017-06-12 01:16:46 -07001797TEST_F(WebRtcVideoChannelTest, UsesCorrectSettingsForScreencast) {
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001798 static const int kScreenshareMinBitrateKbps = 800;
magjed509e4fe2016-11-18 01:34:11 -08001799 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001800 cricket::VideoSendParameters parameters;
1801 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001802 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001803 AddSendStream();
1804
deadbeef5a4a75a2016-06-02 16:23:38 -07001805 cricket::FakeVideoCapturer capturer;
nisse05103312016-03-16 02:22:50 -07001806 VideoOptions min_bitrate_options;
1807 min_bitrate_options.screencast_min_bitrate_kbps =
1808 rtc::Optional<int>(kScreenshareMinBitrateKbps);
deadbeef5a4a75a2016-06-02 16:23:38 -07001809 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &min_bitrate_options,
1810 &capturer));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001811 cricket::VideoFormat capture_format_hd =
1812 capturer.GetSupportedFormats()->front();
1813 EXPECT_EQ(1280, capture_format_hd.width);
1814 EXPECT_EQ(720, capture_format_hd.height);
1815 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1816
1817 EXPECT_TRUE(channel_->SetSend(true));
1818
1819 EXPECT_TRUE(capturer.CaptureFrame());
1820 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1821 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1822
1823 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1824
1825 // Verify non-screencast settings.
perkj26091b12016-09-01 01:17:40 -07001826 webrtc::VideoEncoderConfig encoder_config =
1827 send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02001828 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001829 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07001830 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
1831 EXPECT_EQ(capture_format_hd.width, streams.front().width);
1832 EXPECT_EQ(capture_format_hd.height, streams.front().height);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001833 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
1834 << "Non-screenshare shouldn't use min-transmit bitrate.";
1835
deadbeef5a4a75a2016-06-02 16:23:38 -07001836 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkjd533aec2017-01-13 05:57:25 -08001837 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
nisse05103312016-03-16 02:22:50 -07001838 VideoOptions screencast_options;
1839 screencast_options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001840 EXPECT_TRUE(
1841 channel_->SetVideoSend(last_ssrc_, true, &screencast_options, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08001842 EXPECT_TRUE(capturer.CaptureFrame());
sprangf24a0642017-02-28 13:23:26 -08001843 // Send stream recreated after option change.
1844 ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
1845 send_stream = fake_call_->GetVideoSendStreams().front();
1846 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001847
1848 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07001849 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02001850 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001851 encoder_config.content_type);
1852 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
1853 encoder_config.min_transmit_bitrate_bps);
1854
perkjfa10b552016-10-02 23:45:26 -07001855 streams = send_stream->GetVideoStreams();
1856 EXPECT_EQ(capture_format_hd.width, streams.front().width);
1857 EXPECT_EQ(capture_format_hd.height, streams.front().height);
1858 EXPECT_TRUE(streams[0].temporal_layer_thresholds_bps.empty());
deadbeef5a4a75a2016-06-02 16:23:38 -07001859 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001860}
1861
eladalonf1841382017-06-12 01:16:46 -07001862TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001863 ConferenceModeScreencastConfiguresTemporalLayer) {
Erik Språng2c4c9142015-06-24 11:24:44 +02001864 static const int kConferenceScreencastTemporalBitrateBps =
1865 ScreenshareLayerConfig::GetDefault().tl0_bitrate_kbps * 1000;
nisse4b4dc862016-02-17 05:25:36 -08001866 send_parameters_.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001867 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001868
1869 AddSendStream();
nisse05103312016-03-16 02:22:50 -07001870 VideoOptions options;
1871 options.is_screencast = rtc::Optional<bool>(true);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001872 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07001873 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001874 cricket::VideoFormat capture_format_hd =
1875 capturer.GetSupportedFormats()->front();
1876 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1877
1878 EXPECT_TRUE(channel_->SetSend(true));
1879
1880 EXPECT_TRUE(capturer.CaptureFrame());
1881 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1882 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1883
perkj26091b12016-09-01 01:17:40 -07001884 webrtc::VideoEncoderConfig encoder_config =
1885 send_stream->GetEncoderConfig().Copy();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001886
1887 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07001888 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02001889 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001890 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07001891
1892 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
1893 ASSERT_EQ(1u, streams.size());
1894 ASSERT_EQ(1u, streams[0].temporal_layer_thresholds_bps.size());
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001895 EXPECT_EQ(kConferenceScreencastTemporalBitrateBps,
perkjfa10b552016-10-02 23:45:26 -07001896 streams[0].temporal_layer_thresholds_bps[0]);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001897
deadbeef5a4a75a2016-06-02 16:23:38 -07001898 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001899}
1900
eladalonf1841382017-06-12 01:16:46 -07001901TEST_F(WebRtcVideoChannelTest, SuspendBelowMinBitrateDisabledByDefault) {
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001902 FakeVideoSendStream* stream = AddSendStream();
1903 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1904}
1905
eladalonf1841382017-06-12 01:16:46 -07001906TEST_F(WebRtcVideoChannelTest, SetMediaConfigSuspendBelowMinBitrate) {
kthelgason2bc68642017-02-07 07:02:22 -08001907 MediaConfig media_config = GetMediaConfig();
nisse0db023a2016-03-01 04:29:59 -08001908 media_config.video.suspend_below_min_bitrate = true;
1909
1910 channel_.reset(
1911 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08001912 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08001913
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001914 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001915
1916 FakeVideoSendStream* stream = AddSendStream();
1917 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
1918
nisse0db023a2016-03-01 04:29:59 -08001919 media_config.video.suspend_below_min_bitrate = false;
1920 channel_.reset(
1921 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08001922 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08001923
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001924 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001925
nisse0db023a2016-03-01 04:29:59 -08001926 stream = AddSendStream();
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001927 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1928}
1929
eladalonf1841382017-06-12 01:16:46 -07001930TEST_F(WebRtcVideoChannelTest, Vp8DenoisingEnabledByDefault) {
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001931 FakeVideoSendStream* stream = AddSendStream();
1932 webrtc::VideoCodecVP8 vp8_settings;
1933 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1934 EXPECT_TRUE(vp8_settings.denoisingOn);
1935}
1936
eladalonf1841382017-06-12 01:16:46 -07001937TEST_F(WebRtcVideoChannelTest, VerifyVp8SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001938 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08001939 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001940 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001941
Peter Boström2feafdb2015-09-09 14:32:14 +02001942 // Single-stream settings should apply with RTX as well (verifies that we
1943 // check number of regular SSRCs and not StreamParams::ssrcs which contains
1944 // both RTX and regular SSRCs).
1945 FakeVideoSendStream* stream = SetUpSimulcast(false, true);
Erik Språng143cec12015-04-28 10:01:41 +02001946
1947 cricket::FakeVideoCapturer capturer;
Erik Språng143cec12015-04-28 10:01:41 +02001948 EXPECT_EQ(cricket::CS_RUNNING,
1949 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07001950 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik Språng143cec12015-04-28 10:01:41 +02001951 channel_->SetSend(true);
1952
1953 EXPECT_TRUE(capturer.CaptureFrame());
1954
pbos4cba4eb2015-10-26 11:18:18 -07001955 webrtc::VideoCodecVP8 vp8_settings;
1956 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1957 EXPECT_TRUE(vp8_settings.denoisingOn)
1958 << "VP8 denoising should be on by default.";
1959
nisse05103312016-03-16 02:22:50 -07001960 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001961
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001962 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1963 EXPECT_FALSE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02001964 EXPECT_TRUE(vp8_settings.automaticResizeOn);
1965 EXPECT_TRUE(vp8_settings.frameDroppingOn);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001966
nisse05103312016-03-16 02:22:50 -07001967 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001968
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001969 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1970 EXPECT_TRUE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02001971 EXPECT_TRUE(vp8_settings.automaticResizeOn);
1972 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1973
deadbeef5a4a75a2016-06-02 16:23:38 -07001974 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boström2feafdb2015-09-09 14:32:14 +02001975 stream = SetUpSimulcast(true, false);
deadbeef5a4a75a2016-06-02 16:23:38 -07001976 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik Språng143cec12015-04-28 10:01:41 +02001977 channel_->SetSend(true);
1978 EXPECT_TRUE(capturer.CaptureFrame());
1979
1980 EXPECT_EQ(3, stream->GetVideoStreams().size());
1981 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1982 // Autmatic resize off when using simulcast.
1983 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1984 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1985
1986 // In screen-share mode, denoising is forced off and simulcast disabled.
nisse05103312016-03-16 02:22:50 -07001987 VideoOptions options;
1988 options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001989 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001990
nisse05103312016-03-16 02:22:50 -07001991 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02001992
1993 EXPECT_EQ(1, stream->GetVideoStreams().size());
1994 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1995 EXPECT_FALSE(vp8_settings.denoisingOn);
1996 // Resizing and frame dropping always off for screen sharing.
1997 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1998 EXPECT_FALSE(vp8_settings.frameDroppingOn);
1999
nisse05103312016-03-16 02:22:50 -07002000 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
Erik Språng143cec12015-04-28 10:01:41 +02002001
2002 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2003 EXPECT_FALSE(vp8_settings.denoisingOn);
2004 EXPECT_FALSE(vp8_settings.automaticResizeOn);
2005 EXPECT_FALSE(vp8_settings.frameDroppingOn);
2006
deadbeef5a4a75a2016-06-02 16:23:38 -07002007 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Erik Språng143cec12015-04-28 10:01:41 +02002008}
2009
deadbeef119760a2016-04-04 11:43:27 -07002010// Test that setting the same options doesn't result in the encoder being
2011// reconfigured.
eladalonf1841382017-06-12 01:16:46 -07002012TEST_F(WebRtcVideoChannelTest, SetIdenticalOptionsDoesntReconfigureEncoder) {
deadbeef119760a2016-04-04 11:43:27 -07002013 VideoOptions options;
2014 cricket::FakeVideoCapturer capturer;
2015
perkjfa10b552016-10-02 23:45:26 -07002016 AddSendStream();
deadbeef119760a2016-04-04 11:43:27 -07002017 EXPECT_EQ(cricket::CS_RUNNING,
2018 capturer.Start(capturer.GetSupportedFormats()->front()));
perkjfa10b552016-10-02 23:45:26 -07002019 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002020 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkjfa10b552016-10-02 23:45:26 -07002021 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2022 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
2023
2024 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
deadbeef5a4a75a2016-06-02 16:23:38 -07002025 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
deadbeef119760a2016-04-04 11:43:27 -07002026 EXPECT_TRUE(capturer.CaptureFrame());
perkjfa10b552016-10-02 23:45:26 -07002027 // Expect 1 reconfigurations at this point from the initial configuration.
2028 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
deadbeef119760a2016-04-04 11:43:27 -07002029
2030 // Set the options one more time and expect no additional reconfigurations.
deadbeef5a4a75a2016-06-02 16:23:38 -07002031 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
perkjfa10b552016-10-02 23:45:26 -07002032 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
2033
2034 // Change |options| and expect 2 reconfigurations.
sprangf24a0642017-02-28 13:23:26 -08002035 options.video_noise_reduction = rtc::Optional<bool>(true);
perkjfa10b552016-10-02 23:45:26 -07002036 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
deadbeef119760a2016-04-04 11:43:27 -07002037 EXPECT_EQ(2, send_stream->num_encoder_reconfigurations());
2038
deadbeef5a4a75a2016-06-02 16:23:38 -07002039 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
deadbeef119760a2016-04-04 11:43:27 -07002040}
2041
eladalonf1841382017-06-12 01:16:46 -07002042class Vp9SettingsTest : public WebRtcVideoChannelTest {
Erik Språng143cec12015-04-28 10:01:41 +02002043 public:
asaperssonc5dabdd2016-03-21 04:15:50 -07002044 Vp9SettingsTest() : Vp9SettingsTest("") {}
2045 explicit Vp9SettingsTest(const char* field_trials)
eladalonf1841382017-06-12 01:16:46 -07002046 : WebRtcVideoChannelTest(field_trials) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +02002047 encoder_factory_->AddSupportedVideoCodecType("VP9");
Erik Språng143cec12015-04-28 10:01:41 +02002048 }
2049 virtual ~Vp9SettingsTest() {}
2050
2051 protected:
Erik Språng143cec12015-04-28 10:01:41 +02002052 void TearDown() override {
2053 // Remove references to encoder_factory_ since this will be destroyed
2054 // before channel_ and engine_.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002055 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
Erik Språng143cec12015-04-28 10:01:41 +02002056 }
Erik Språng143cec12015-04-28 10:01:41 +02002057};
2058
2059TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002060 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002061 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002062 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Erik Språng143cec12015-04-28 10:01:41 +02002063
Peter Boström2feafdb2015-09-09 14:32:14 +02002064 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
Erik Språng143cec12015-04-28 10:01:41 +02002065
2066 cricket::FakeVideoCapturer capturer;
Erik Språng143cec12015-04-28 10:01:41 +02002067 EXPECT_EQ(cricket::CS_RUNNING,
2068 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07002069 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik Språng143cec12015-04-28 10:01:41 +02002070 channel_->SetSend(true);
2071
2072 EXPECT_TRUE(capturer.CaptureFrame());
2073
pbos4cba4eb2015-10-26 11:18:18 -07002074 webrtc::VideoCodecVP9 vp9_settings;
2075 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
jianja5e8aa62017-03-27 10:09:00 -07002076 EXPECT_TRUE(vp9_settings.denoisingOn)
2077 << "VP9 denoising should be on by default.";
pbos4cba4eb2015-10-26 11:18:18 -07002078
nisse05103312016-03-16 02:22:50 -07002079 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02002080
Erik Språng143cec12015-04-28 10:01:41 +02002081 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
2082 EXPECT_FALSE(vp9_settings.denoisingOn);
2083 // Frame dropping always on for real time video.
2084 EXPECT_TRUE(vp9_settings.frameDroppingOn);
2085
nisse05103312016-03-16 02:22:50 -07002086 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
Erik Språng143cec12015-04-28 10:01:41 +02002087
2088 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
2089 EXPECT_TRUE(vp9_settings.denoisingOn);
2090 EXPECT_TRUE(vp9_settings.frameDroppingOn);
2091
2092 // In screen-share mode, denoising is forced off.
nisse05103312016-03-16 02:22:50 -07002093 VideoOptions options;
2094 options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07002095 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08002096
nisse05103312016-03-16 02:22:50 -07002097 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02002098
2099 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
2100 EXPECT_FALSE(vp9_settings.denoisingOn);
2101 // Frame dropping always off for screen sharing.
2102 EXPECT_FALSE(vp9_settings.frameDroppingOn);
2103
nisse05103312016-03-16 02:22:50 -07002104 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik Språng143cec12015-04-28 10:01:41 +02002105
2106 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
2107 EXPECT_FALSE(vp9_settings.denoisingOn);
2108 EXPECT_FALSE(vp9_settings.frameDroppingOn);
2109
deadbeef5a4a75a2016-06-02 16:23:38 -07002110 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002111}
2112
asaperssonc5dabdd2016-03-21 04:15:50 -07002113class Vp9SettingsTestWithFieldTrial : public Vp9SettingsTest {
2114 public:
brandtr468da7c2016-11-22 02:16:47 -08002115 explicit Vp9SettingsTestWithFieldTrial(const char* field_trials)
asaperssonc5dabdd2016-03-21 04:15:50 -07002116 : Vp9SettingsTest(field_trials) {}
2117
2118 protected:
2119 void VerifySettings(int num_spatial_layers, int num_temporal_layers) {
2120 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002121 parameters.codecs.push_back(GetEngineCodec("VP9"));
asaperssonc5dabdd2016-03-21 04:15:50 -07002122 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2123
2124 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
2125
2126 cricket::FakeVideoCapturer capturer;
2127 EXPECT_EQ(cricket::CS_RUNNING,
2128 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07002129 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
asaperssonc5dabdd2016-03-21 04:15:50 -07002130 channel_->SetSend(true);
2131
2132 EXPECT_TRUE(capturer.CaptureFrame());
2133
2134 webrtc::VideoCodecVP9 vp9_settings;
2135 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
2136 EXPECT_EQ(num_spatial_layers, vp9_settings.numberOfSpatialLayers);
2137 EXPECT_EQ(num_temporal_layers, vp9_settings.numberOfTemporalLayers);
2138
deadbeef5a4a75a2016-06-02 16:23:38 -07002139 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
asaperssonc5dabdd2016-03-21 04:15:50 -07002140 }
2141};
2142
2143class Vp9SettingsTestWithNoFlag : public Vp9SettingsTestWithFieldTrial {
2144 public:
2145 Vp9SettingsTestWithNoFlag() : Vp9SettingsTestWithFieldTrial("") {}
2146};
2147
2148TEST_F(Vp9SettingsTestWithNoFlag, VerifySettings) {
2149 const int kNumSpatialLayers = 1;
2150 const int kNumTemporalLayers = 1;
2151 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
2152}
2153
2154class Vp9SettingsTestWithInvalidFlag : public Vp9SettingsTestWithFieldTrial {
2155 public:
2156 Vp9SettingsTestWithInvalidFlag()
2157 : Vp9SettingsTestWithFieldTrial("WebRTC-SupportVP9SVC/Default/") {}
2158};
2159
2160TEST_F(Vp9SettingsTestWithInvalidFlag, VerifySettings) {
2161 const int kNumSpatialLayers = 1;
2162 const int kNumTemporalLayers = 1;
2163 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
2164}
2165
2166class Vp9SettingsTestWith2SL3TLFlag : public Vp9SettingsTestWithFieldTrial {
2167 public:
2168 Vp9SettingsTestWith2SL3TLFlag()
2169 : Vp9SettingsTestWithFieldTrial(
2170 "WebRTC-SupportVP9SVC/EnabledByFlag_2SL3TL/") {}
2171};
2172
2173TEST_F(Vp9SettingsTestWith2SL3TLFlag, VerifySettings) {
2174 const int kNumSpatialLayers = 2;
2175 const int kNumTemporalLayers = 3;
2176 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
2177}
2178
asapersson3c81a1a2017-06-14 05:52:21 -07002179TEST_F(WebRtcVideoChannelTest,
2180 BalancedDegradationPreferenceNotSupportedWithoutFieldtrial) {
2181 webrtc::test::ScopedFieldTrials override_field_trials_(
2182 "WebRTC-Video-BalancedDegradation/Disabled/");
2183 const bool kResolutionScalingEnabled = true;
2184 const bool kFpsScalingEnabled = false;
2185 TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
2186}
2187
2188TEST_F(WebRtcVideoChannelTest,
2189 BalancedDegradationPreferenceSupportedBehindFieldtrial) {
2190 webrtc::test::ScopedFieldTrials override_field_trials_(
2191 "WebRTC-Video-BalancedDegradation/Enabled/");
2192 const bool kResolutionScalingEnabled = true;
2193 const bool kFpsScalingEnabled = true;
2194 TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
2195}
2196
eladalonf1841382017-06-12 01:16:46 -07002197TEST_F(WebRtcVideoChannelTest, AdaptsOnOveruse) {
Erik Språngefbde372015-04-29 16:21:28 +02002198 TestCpuAdaptation(true, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002199}
2200
eladalonf1841382017-06-12 01:16:46 -07002201TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenDisabled) {
Erik Språngefbde372015-04-29 16:21:28 +02002202 TestCpuAdaptation(false, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002203}
2204
eladalonf1841382017-06-12 01:16:46 -07002205TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenScreensharing) {
Erik Språngefbde372015-04-29 16:21:28 +02002206 TestCpuAdaptation(true, true);
2207}
2208
eladalonf1841382017-06-12 01:16:46 -07002209TEST_F(WebRtcVideoChannelTest, AdaptsOnOveruseAndChangeResolution) {
magjed509e4fe2016-11-18 01:34:11 -08002210 cricket::VideoCodec codec = GetEngineCodec("VP8");
perkj2d5f0912016-02-29 00:04:41 -08002211 cricket::VideoSendParameters parameters;
2212 parameters.codecs.push_back(codec);
2213
kthelgason2bc68642017-02-07 07:02:22 -08002214 MediaConfig media_config = GetMediaConfig();
perkj2d5f0912016-02-29 00:04:41 -08002215 channel_.reset(
2216 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002217 channel_->OnReadyToSend(true);
perkj2d5f0912016-02-29 00:04:41 -08002218 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2219
2220 AddSendStream();
2221
2222 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002223 ASSERT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08002224 ASSERT_EQ(cricket::CS_RUNNING,
2225 capturer.Start(capturer.GetSupportedFormats()->front()));
2226 ASSERT_TRUE(channel_->SetSend(true));
2227
2228 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2229 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
perkj2d5f0912016-02-29 00:04:41 -08002230
2231 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2232 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2233 EXPECT_EQ(1280, send_stream->GetLastWidth());
2234 EXPECT_EQ(720, send_stream->GetLastHeight());
2235
2236 // Trigger overuse.
perkj803d97f2016-11-01 11:45:46 -07002237 rtc::VideoSinkWants wants;
sprangc5d62e22017-04-02 23:53:04 -07002238 wants.max_pixel_count =
2239 send_stream->GetLastWidth() * send_stream->GetLastHeight() - 1;
perkj803d97f2016-11-01 11:45:46 -07002240 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002241 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2242 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
2243 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2244 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2245
2246 // Trigger overuse again.
sprangc5d62e22017-04-02 23:53:04 -07002247 wants.max_pixel_count =
2248 send_stream->GetLastWidth() * send_stream->GetLastHeight() - 1;
perkj803d97f2016-11-01 11:45:46 -07002249 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002250 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2251 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
2252 EXPECT_EQ(1280 * 2 / 4, send_stream->GetLastWidth());
2253 EXPECT_EQ(720 * 2 / 4, send_stream->GetLastHeight());
2254
2255 // Change input resolution.
2256 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
perkj803d97f2016-11-01 11:45:46 -07002257 EXPECT_EQ(4, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002258 EXPECT_EQ(1284 / 2, send_stream->GetLastWidth());
2259 EXPECT_EQ(724 / 2, send_stream->GetLastHeight());
2260
2261 // Trigger underuse which should go back up in resolution.
sprang84a37592017-02-10 07:04:27 -08002262 int current_pixel_count =
2263 send_stream->GetLastWidth() * send_stream->GetLastHeight();
2264 // Cap the max to 4x the pixel count (assuming max 1/2 x 1/2 scale downs)
2265 // of the current stream, so we don't take too large steps.
sprangc5d62e22017-04-02 23:53:04 -07002266 wants.max_pixel_count = current_pixel_count * 4;
sprang84a37592017-02-10 07:04:27 -08002267 // Default step down is 3/5 pixel count, so go up by 5/3.
2268 wants.target_pixel_count = rtc::Optional<int>((current_pixel_count * 5) / 3);
perkj803d97f2016-11-01 11:45:46 -07002269 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002270 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
perkj803d97f2016-11-01 11:45:46 -07002271 EXPECT_EQ(5, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002272 EXPECT_EQ(1284 * 3 / 4, send_stream->GetLastWidth());
2273 EXPECT_EQ(724 * 3 / 4, send_stream->GetLastHeight());
2274
sprang84a37592017-02-10 07:04:27 -08002275 // Trigger underuse again, should go back up to full resolution.
2276 current_pixel_count =
2277 send_stream->GetLastWidth() * send_stream->GetLastHeight();
sprangc5d62e22017-04-02 23:53:04 -07002278 wants.max_pixel_count = current_pixel_count * 4;
sprang84a37592017-02-10 07:04:27 -08002279 wants.target_pixel_count = rtc::Optional<int>((current_pixel_count * 5) / 3);
perkj803d97f2016-11-01 11:45:46 -07002280 send_stream->InjectVideoSinkWants(wants);
perkj2d5f0912016-02-29 00:04:41 -08002281 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
perkj803d97f2016-11-01 11:45:46 -07002282 EXPECT_EQ(6, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002283 EXPECT_EQ(1284, send_stream->GetLastWidth());
2284 EXPECT_EQ(724, send_stream->GetLastHeight());
2285
deadbeef5a4a75a2016-06-02 16:23:38 -07002286 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkj2d5f0912016-02-29 00:04:41 -08002287}
2288
eladalonf1841382017-06-12 01:16:46 -07002289TEST_F(WebRtcVideoChannelTest, PreviousAdaptationDoesNotApplyToScreenshare) {
magjed509e4fe2016-11-18 01:34:11 -08002290 cricket::VideoCodec codec = GetEngineCodec("VP8");
Per766ad3b2016-04-05 15:23:49 +02002291 cricket::VideoSendParameters parameters;
2292 parameters.codecs.push_back(codec);
2293
kthelgason2bc68642017-02-07 07:02:22 -08002294 MediaConfig media_config = GetMediaConfig();
2295 media_config.video.enable_cpu_overuse_detection = true;
Per766ad3b2016-04-05 15:23:49 +02002296 channel_.reset(
2297 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002298 channel_->OnReadyToSend(true);
Per766ad3b2016-04-05 15:23:49 +02002299 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2300
2301 AddSendStream();
2302
2303 cricket::FakeVideoCapturer capturer;
Per766ad3b2016-04-05 15:23:49 +02002304 ASSERT_EQ(cricket::CS_RUNNING,
2305 capturer.Start(capturer.GetSupportedFormats()->front()));
2306 ASSERT_TRUE(channel_->SetSend(true));
2307 cricket::VideoOptions camera_options;
perkj803d97f2016-11-01 11:45:46 -07002308 camera_options.is_screencast = rtc::Optional<bool>(false);
deadbeef5a4a75a2016-06-02 16:23:38 -07002309 channel_->SetVideoSend(last_ssrc_, true /* enable */, &camera_options,
2310 &capturer);
Per766ad3b2016-04-05 15:23:49 +02002311
2312 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2313 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
Per766ad3b2016-04-05 15:23:49 +02002314
2315 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2316 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2317 EXPECT_EQ(1280, send_stream->GetLastWidth());
2318 EXPECT_EQ(720, send_stream->GetLastHeight());
2319
2320 // Trigger overuse.
perkj803d97f2016-11-01 11:45:46 -07002321 rtc::VideoSinkWants wants;
sprangc5d62e22017-04-02 23:53:04 -07002322 wants.max_pixel_count =
2323 send_stream->GetLastWidth() * send_stream->GetLastHeight() - 1;
perkj803d97f2016-11-01 11:45:46 -07002324 send_stream->InjectVideoSinkWants(wants);
Per766ad3b2016-04-05 15:23:49 +02002325 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2326 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
2327 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2328 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2329
2330 // Switch to screen share. Expect no CPU adaptation.
2331 cricket::FakeVideoCapturer screen_share(true);
2332 ASSERT_EQ(cricket::CS_RUNNING,
2333 screen_share.Start(screen_share.GetSupportedFormats()->front()));
Per766ad3b2016-04-05 15:23:49 +02002334 cricket::VideoOptions screenshare_options;
2335 screenshare_options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07002336 channel_->SetVideoSend(last_ssrc_, true /* enable */, &screenshare_options,
2337 &screen_share);
Per766ad3b2016-04-05 15:23:49 +02002338 EXPECT_TRUE(screen_share.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
sprangf24a0642017-02-28 13:23:26 -08002339 ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
2340 send_stream = fake_call_->GetVideoSendStreams().front();
2341 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
Per766ad3b2016-04-05 15:23:49 +02002342 EXPECT_EQ(1284, send_stream->GetLastWidth());
2343 EXPECT_EQ(724, send_stream->GetLastHeight());
2344
2345 // Switch back to the normal capturer. Expect the frame to be CPU adapted.
deadbeef5a4a75a2016-06-02 16:23:38 -07002346 channel_->SetVideoSend(last_ssrc_, true /* enable */, &camera_options,
2347 &capturer);
sprangf24a0642017-02-28 13:23:26 -08002348 send_stream = fake_call_->GetVideoSendStreams().front();
2349 // We have a new fake send stream, so it doesn't remember the old sink wants.
2350 // In practice, it will be populated from
mflodmancc3d4422017-08-03 08:27:51 -07002351 // VideoStreamEncoder::VideoSourceProxy::SetSource(), so simulate that here.
sprangf24a0642017-02-28 13:23:26 -08002352 send_stream->InjectVideoSinkWants(wants);
Per766ad3b2016-04-05 15:23:49 +02002353 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
sprangf24a0642017-02-28 13:23:26 -08002354 ASSERT_EQ(3, fake_call_->GetNumCreatedSendStreams());
2355 send_stream = fake_call_->GetVideoSendStreams().front();
2356 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
Per766ad3b2016-04-05 15:23:49 +02002357 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2358 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2359
deadbeef5a4a75a2016-06-02 16:23:38 -07002360 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Per766ad3b2016-04-05 15:23:49 +02002361}
2362
asapersson3c81a1a2017-06-14 05:52:21 -07002363// TODO(asapersson): Remove this test when the balanced field trial is removed.
2364void WebRtcVideoChannelTest::TestDegradationPreference(
2365 bool resolution_scaling_enabled,
2366 bool fps_scaling_enabled) {
2367 cricket::VideoCodec codec = GetEngineCodec("VP8");
2368 cricket::VideoSendParameters parameters;
2369 parameters.codecs.push_back(codec);
2370
2371 MediaConfig media_config = GetMediaConfig();
2372 media_config.video.enable_cpu_overuse_detection = true;
2373 channel_.reset(
2374 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
2375 channel_->OnReadyToSend(true);
2376
2377 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2378
2379 AddSendStream();
2380
2381 cricket::FakeVideoCapturer capturer;
2382 VideoOptions options;
2383 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
2384 cricket::VideoFormat capture_format = capturer.GetSupportedFormats()->front();
2385 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format));
2386
2387 EXPECT_TRUE(channel_->SetSend(true));
2388
2389 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
2390 EXPECT_EQ(resolution_scaling_enabled,
2391 send_stream->resolution_scaling_enabled());
2392 EXPECT_EQ(fps_scaling_enabled, send_stream->framerate_scaling_enabled());
2393
2394 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
2395}
2396
eladalonf1841382017-06-12 01:16:46 -07002397void WebRtcVideoChannelTest::TestCpuAdaptation(bool enable_overuse,
2398 bool is_screenshare) {
sprangc5d62e22017-04-02 23:53:04 -07002399 const int kDefaultFps = 30;
magjed509e4fe2016-11-18 01:34:11 -08002400 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002401 cricket::VideoSendParameters parameters;
2402 parameters.codecs.push_back(codec);
nisse51542be2016-02-12 02:27:06 -08002403
kthelgason2bc68642017-02-07 07:02:22 -08002404 MediaConfig media_config = GetMediaConfig();
2405 if (enable_overuse) {
2406 media_config.video.enable_cpu_overuse_detection = true;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002407 }
nisse51542be2016-02-12 02:27:06 -08002408 channel_.reset(
2409 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002410 channel_->OnReadyToSend(true);
nisse51542be2016-02-12 02:27:06 -08002411
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002412 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002413
2414 AddSendStream();
2415
deadbeef5a4a75a2016-06-02 16:23:38 -07002416 cricket::FakeVideoCapturer capturer;
nisse05103312016-03-16 02:22:50 -07002417 VideoOptions options;
2418 options.is_screencast = rtc::Optional<bool>(is_screenshare);
deadbeef5a4a75a2016-06-02 16:23:38 -07002419 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
perkj26752742016-10-24 01:21:16 -07002420 cricket::VideoFormat capture_format = capturer.GetSupportedFormats()->front();
sprangc5d62e22017-04-02 23:53:04 -07002421 capture_format.interval = rtc::kNumNanosecsPerSec / kDefaultFps;
perkj26752742016-10-24 01:21:16 -07002422 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002423
2424 EXPECT_TRUE(channel_->SetSend(true));
2425
solenberge5269742015-09-08 05:13:22 -07002426 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
perkj2d5f0912016-02-29 00:04:41 -08002427
sprangc5d62e22017-04-02 23:53:04 -07002428 if (!enable_overuse) {
perkj803d97f2016-11-01 11:45:46 -07002429 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
sprangc5d62e22017-04-02 23:53:04 -07002430 EXPECT_FALSE(send_stream->framerate_scaling_enabled());
2431 EXPECT_EQ(is_screenshare, send_stream->framerate_scaling_enabled());
perkj2d5f0912016-02-29 00:04:41 -08002432
2433 EXPECT_TRUE(capturer.CaptureFrame());
2434 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2435
perkj26752742016-10-24 01:21:16 -07002436 EXPECT_EQ(capture_format.width, send_stream->GetLastWidth());
2437 EXPECT_EQ(capture_format.height, send_stream->GetLastHeight());
perkj2d5f0912016-02-29 00:04:41 -08002438
deadbeef5a4a75a2016-06-02 16:23:38 -07002439 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkj2d5f0912016-02-29 00:04:41 -08002440 return;
2441 }
2442
sprangc5d62e22017-04-02 23:53:04 -07002443 if (is_screenshare) {
2444 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
2445 EXPECT_TRUE(send_stream->framerate_scaling_enabled());
2446 } else {
2447 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
2448 EXPECT_FALSE(send_stream->framerate_scaling_enabled());
2449 }
2450
perkj803d97f2016-11-01 11:45:46 -07002451 // Trigger overuse.
2452 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2453
2454 rtc::VideoSinkWants wants;
sprangc5d62e22017-04-02 23:53:04 -07002455 if (is_screenshare) {
2456 wants.max_framerate_fps = (kDefaultFps * 2) / 3;
2457 } else {
2458 wants.max_pixel_count = capture_format.width * capture_format.height - 1;
2459 }
perkj803d97f2016-11-01 11:45:46 -07002460 send_stream->InjectVideoSinkWants(wants);
2461
sprangc5d62e22017-04-02 23:53:04 -07002462 for (int i = 0; i < kDefaultFps; ++i)
2463 EXPECT_TRUE(capturer.CaptureFrame());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002464
sprangc5d62e22017-04-02 23:53:04 -07002465 if (is_screenshare) {
2466 // Drops every third frame.
2467 EXPECT_EQ(kDefaultFps * 2 / 3, send_stream->GetNumberOfSwappedFrames());
2468 EXPECT_EQ(send_stream->GetLastWidth(), capture_format.width);
2469 EXPECT_EQ(send_stream->GetLastHeight(), capture_format.height);
2470 } else {
2471 EXPECT_EQ(kDefaultFps, send_stream->GetNumberOfSwappedFrames());
2472 EXPECT_LT(send_stream->GetLastWidth(), capture_format.width);
2473 EXPECT_LT(send_stream->GetLastHeight(), capture_format.height);
2474 }
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002475
2476 // Trigger underuse which should go back to normal resolution.
sprang84a37592017-02-10 07:04:27 -08002477 int last_pixel_count =
2478 send_stream->GetLastWidth() * send_stream->GetLastHeight();
sprangc5d62e22017-04-02 23:53:04 -07002479 if (is_screenshare) {
2480 wants.max_framerate_fps = kDefaultFps;
2481 } else {
2482 wants.max_pixel_count = last_pixel_count * 4;
2483 wants.target_pixel_count.emplace((last_pixel_count * 5) / 3);
2484 }
perkj803d97f2016-11-01 11:45:46 -07002485 send_stream->InjectVideoSinkWants(wants);
2486
sprangc5d62e22017-04-02 23:53:04 -07002487 for (int i = 0; i < kDefaultFps; ++i)
2488 EXPECT_TRUE(capturer.CaptureFrame());
2489
2490 if (is_screenshare) {
2491 EXPECT_EQ(kDefaultFps + (kDefaultFps * 2 / 3),
2492 send_stream->GetNumberOfSwappedFrames());
2493 } else {
2494 EXPECT_EQ(kDefaultFps * 2, send_stream->GetNumberOfSwappedFrames());
2495 }
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002496
perkj26752742016-10-24 01:21:16 -07002497 EXPECT_EQ(capture_format.width, send_stream->GetLastWidth());
2498 EXPECT_EQ(capture_format.height, send_stream->GetLastHeight());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002499
deadbeef5a4a75a2016-06-02 16:23:38 -07002500 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002501}
2502
eladalonf1841382017-06-12 01:16:46 -07002503TEST_F(WebRtcVideoChannelTest, EstimatesNtpStartTimeCorrectly) {
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002504 // Start at last timestamp to verify that wraparounds are estimated correctly.
2505 static const uint32_t kInitialTimestamp = 0xFFFFFFFFu;
2506 static const int64_t kInitialNtpTimeMs = 1247891230;
2507 static const int kFrameOffsetMs = 20;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002508 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002509
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002510 FakeVideoReceiveStream* stream = AddRecvStream();
2511 cricket::FakeVideoRenderer renderer;
nisse08582ff2016-02-04 01:24:52 -08002512 EXPECT_TRUE(channel_->SetSink(last_ssrc_, &renderer));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002513
nisse64ec8f82016-09-27 00:17:25 -07002514 webrtc::VideoFrame video_frame(CreateBlackFrameBuffer(4, 4),
2515 kInitialTimestamp, 0,
2516 webrtc::kVideoRotation_0);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002517 // Initial NTP time is not available on the first frame, but should still be
2518 // able to be estimated.
nisseeb83a1a2016-03-21 01:27:56 -07002519 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002520
2521 EXPECT_EQ(1, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002522
2523 // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which
2524 // triggers a constant-overflow warning, hence we're calculating it explicitly
2525 // here.
2526 video_frame.set_timestamp(kFrameOffsetMs * 90 - 1);
2527 video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs);
nisseeb83a1a2016-03-21 01:27:56 -07002528 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002529
2530 EXPECT_EQ(2, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002531
2532 // Verify that NTP time has been correctly deduced.
2533 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002534 ASSERT_TRUE(channel_->GetStats(&info));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002535 ASSERT_EQ(1u, info.receivers.size());
2536 EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002537}
2538
eladalonf1841382017-06-12 01:16:46 -07002539TEST_F(WebRtcVideoChannelTest, SetDefaultSendCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002540 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002541
2542 VideoCodec codec;
2543 EXPECT_TRUE(channel_->GetSendCodec(&codec));
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00002544 EXPECT_TRUE(codec.Matches(engine_.codecs()[0]));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002545
2546 // Using a RTX setup to verify that the default RTX payload type is good.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002547 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
2548 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002549 FakeVideoSendStream* stream = AddSendStream(
2550 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
perkj26091b12016-09-01 01:17:40 -07002551 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002552
2553 // Make sure NACK and FEC are enabled on the correct payload types.
2554 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
magjed509e4fe2016-11-18 01:34:11 -08002555 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
2556 EXPECT_EQ(GetEngineCodec("red").id, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002557
2558 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
2559 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
Shao Changbine62202f2015-04-21 20:24:50 +08002560 VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002561 // TODO(juberti): Check RTCP, PLI, TMMBR.
2562}
2563
brandtr31bd2242017-05-19 05:47:46 -07002564// The following four tests ensures that FlexFEC is not activated by default
2565// when the field trials are not enabled.
2566// TODO(brandtr): Remove or update these tests when FlexFEC _is_ enabled by
2567// default.
eladalonf1841382017-06-12 01:16:46 -07002568TEST_F(WebRtcVideoChannelTest,
brandtr31bd2242017-05-19 05:47:46 -07002569 FlexfecSendCodecWithoutSsrcNotExposedByDefault) {
brandtr468da7c2016-11-22 02:16:47 -08002570 FakeVideoSendStream* stream = AddSendStream();
2571 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2572
brandtr3d200bd2017-01-16 06:59:19 -08002573 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr31bd2242017-05-19 05:47:46 -07002574 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
2575 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
brandtr468da7c2016-11-22 02:16:47 -08002576}
2577
eladalonf1841382017-06-12 01:16:46 -07002578TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithSsrcNotExposedByDefault) {
brandtr468da7c2016-11-22 02:16:47 -08002579 FakeVideoSendStream* stream = AddSendStream(
2580 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2581 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2582
brandtr3d200bd2017-01-16 06:59:19 -08002583 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr31bd2242017-05-19 05:47:46 -07002584 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
2585 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
2586}
2587
eladalonf1841382017-06-12 01:16:46 -07002588TEST_F(WebRtcVideoChannelTest,
brandtr31bd2242017-05-19 05:47:46 -07002589 FlexfecRecvCodecWithoutSsrcNotExposedByDefault) {
2590 AddRecvStream();
2591
2592 const std::vector<FakeFlexfecReceiveStream*>& streams =
2593 fake_call_->GetFlexfecReceiveStreams();
2594 EXPECT_TRUE(streams.empty());
2595}
2596
eladalonf1841382017-06-12 01:16:46 -07002597TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithSsrcNotExposedByDefault) {
brandtr31bd2242017-05-19 05:47:46 -07002598 AddRecvStream(
2599 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2600
2601 const std::vector<FakeFlexfecReceiveStream*>& streams =
2602 fake_call_->GetFlexfecReceiveStreams();
2603 EXPECT_TRUE(streams.empty());
brandtr468da7c2016-11-22 02:16:47 -08002604}
2605
2606// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
2607// tests that use this test fixture into the corresponding "non-field trial"
2608// tests.
eladalonf1841382017-06-12 01:16:46 -07002609class WebRtcVideoChannelFlexfecRecvTest : public WebRtcVideoChannelTest {
brandtr468da7c2016-11-22 02:16:47 -08002610 public:
eladalonf1841382017-06-12 01:16:46 -07002611 WebRtcVideoChannelFlexfecRecvTest()
2612 : WebRtcVideoChannelTest("WebRTC-FlexFEC-03-Advertised/Enabled/") {}
brandtr468da7c2016-11-22 02:16:47 -08002613};
2614
eladalonf1841382017-06-12 01:16:46 -07002615TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr36e7d702017-01-13 07:15:54 -08002616 DefaultFlexfecCodecHasTransportCcAndRembFeedbackParam) {
2617 EXPECT_TRUE(cricket::HasTransportCc(GetEngineCodec("flexfec-03")));
2618 EXPECT_TRUE(cricket::HasRemb(GetEngineCodec("flexfec-03")));
2619}
2620
eladalonf1841382017-06-12 01:16:46 -07002621TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithoutSsrc) {
brandtr31bd2242017-05-19 05:47:46 -07002622 AddRecvStream();
2623
2624 const std::vector<FakeFlexfecReceiveStream*>& streams =
2625 fake_call_->GetFlexfecReceiveStreams();
2626 EXPECT_TRUE(streams.empty());
2627}
2628
eladalonf1841382017-06-12 01:16:46 -07002629TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithSsrc) {
brandtr31bd2242017-05-19 05:47:46 -07002630 AddRecvStream(
2631 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2632
2633 const std::vector<FakeFlexfecReceiveStream*>& streams =
2634 fake_call_->GetFlexfecReceiveStreams();
2635 ASSERT_EQ(1U, streams.size());
2636 const FakeFlexfecReceiveStream* stream = streams.front();
2637 const webrtc::FlexfecReceiveStream::Config& config = stream->GetConfig();
2638 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.payload_type);
2639 EXPECT_EQ(kFlexfecSsrc, config.remote_ssrc);
2640 ASSERT_EQ(1U, config.protected_media_ssrcs.size());
2641 EXPECT_EQ(kSsrcs1[0], config.protected_media_ssrcs[0]);
brandtr7cd28b92017-09-22 00:26:25 -07002642
2643 const std::vector<FakeVideoReceiveStream*>& video_streams =
2644 fake_call_->GetVideoReceiveStreams();
2645 ASSERT_EQ(1U, video_streams.size());
2646 const webrtc::VideoReceiveStream::Config& video_config =
2647 video_streams.front()->GetConfig();
2648 EXPECT_TRUE(video_config.rtp.protected_by_flexfec);
brandtr31bd2242017-05-19 05:47:46 -07002649}
2650
eladalonf1841382017-06-12 01:16:46 -07002651TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr11fb4722017-05-30 01:31:37 -07002652 EnablingFlexfecDoesNotRecreateVideoReceiveStream) {
2653 cricket::VideoRecvParameters recv_parameters;
2654 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
2655 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
2656
2657 AddRecvStream(
2658 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2659 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2660 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
2661
2662 // Enable FlexFEC.
2663 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2664 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
2665 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams())
2666 << "Enabling FlexFEC should create FlexfecReceiveStream.";
2667 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
2668 << "Enabling FlexFEC should not create VideoReceiveStream.";
2669 EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size())
2670 << "Enabling FlexFEC should create a single FlexfecReceiveStream.";
2671}
2672
eladalonf1841382017-06-12 01:16:46 -07002673TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr11fb4722017-05-30 01:31:37 -07002674 DisablingFlexfecDoesNotRecreateVideoReceiveStream) {
2675 cricket::VideoRecvParameters recv_parameters;
2676 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
2677 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2678 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
2679
2680 AddRecvStream(
2681 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2682 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
2683 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
2684 EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size());
2685
2686 // Disable FlexFEC.
2687 recv_parameters.codecs.clear();
2688 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
2689 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
2690 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams())
2691 << "Disabling FlexFEC should not recreate VideoReceiveStream.";
2692 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
2693 << "Disabling FlexFEC should not destroy VideoReceiveStream.";
2694 EXPECT_TRUE(fake_call_->GetFlexfecReceiveStreams().empty())
2695 << "Disabling FlexFEC should destroy FlexfecReceiveStream.";
2696}
2697
brandtr31bd2242017-05-19 05:47:46 -07002698// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
2699// tests that use this test fixture into the corresponding "non-field trial"
2700// tests.
eladalonf1841382017-06-12 01:16:46 -07002701class WebRtcVideoChannelFlexfecSendRecvTest : public WebRtcVideoChannelTest {
brandtr31bd2242017-05-19 05:47:46 -07002702 public:
eladalonf1841382017-06-12 01:16:46 -07002703 WebRtcVideoChannelFlexfecSendRecvTest()
2704 : WebRtcVideoChannelTest(
brandtr31bd2242017-05-19 05:47:46 -07002705 "WebRTC-FlexFEC-03-Advertised/Enabled/WebRTC-FlexFEC-03/Enabled/") {
2706 }
2707};
2708
eladalonf1841382017-06-12 01:16:46 -07002709TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07002710 SetDefaultSendCodecsWithoutSsrc) {
brandtr468da7c2016-11-22 02:16:47 -08002711 FakeVideoSendStream* stream = AddSendStream();
2712 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2713
brandtr3d200bd2017-01-16 06:59:19 -08002714 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
2715 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
2716 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
brandtr468da7c2016-11-22 02:16:47 -08002717}
2718
eladalonf1841382017-06-12 01:16:46 -07002719TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithSsrc) {
brandtr468da7c2016-11-22 02:16:47 -08002720 FakeVideoSendStream* stream = AddSendStream(
2721 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2722 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2723
brandtr3d200bd2017-01-16 06:59:19 -08002724 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
2725 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
2726 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
2727 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08002728}
2729
eladalonf1841382017-06-12 01:16:46 -07002730TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002731 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002732 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002733 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002734
2735 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07002736 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002737
brandtrb5f2c3f2016-10-04 23:28:39 -07002738 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type);
2739 EXPECT_EQ(-1, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002740}
2741
eladalonf1841382017-06-12 01:16:46 -07002742TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetSendCodecsWithoutFec) {
brandtr468da7c2016-11-22 02:16:47 -08002743 cricket::VideoSendParameters parameters;
2744 parameters.codecs.push_back(GetEngineCodec("VP8"));
2745 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2746
2747 FakeVideoSendStream* stream = AddSendStream();
2748 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2749
brandtr3d200bd2017-01-16 06:59:19 -08002750 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr468da7c2016-11-22 02:16:47 -08002751}
2752
eladalonf1841382017-06-12 01:16:46 -07002753TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvCodecsWithFec) {
brandtr9c3d4c42017-01-23 06:59:13 -08002754 AddRecvStream(
2755 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08002756
2757 cricket::VideoRecvParameters recv_parameters;
2758 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
2759 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2760 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
brandtr9d58d942017-02-03 04:43:41 -08002761
2762 const std::vector<FakeFlexfecReceiveStream*>& flexfec_streams =
2763 fake_call_->GetFlexfecReceiveStreams();
2764 ASSERT_EQ(1U, flexfec_streams.size());
2765 const FakeFlexfecReceiveStream* flexfec_stream = flexfec_streams.front();
2766 const webrtc::FlexfecReceiveStream::Config& flexfec_stream_config =
2767 flexfec_stream->GetConfig();
brandtr9c3d4c42017-01-23 06:59:13 -08002768 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9d58d942017-02-03 04:43:41 -08002769 flexfec_stream_config.payload_type);
2770 EXPECT_EQ(kFlexfecSsrc, flexfec_stream_config.remote_ssrc);
2771 ASSERT_EQ(1U, flexfec_stream_config.protected_media_ssrcs.size());
2772 EXPECT_EQ(kSsrcs1[0], flexfec_stream_config.protected_media_ssrcs[0]);
2773 const std::vector<FakeVideoReceiveStream*>& video_streams =
2774 fake_call_->GetVideoReceiveStreams();
2775 const FakeVideoReceiveStream* video_stream = video_streams.front();
2776 const webrtc::VideoReceiveStream::Config& video_stream_config =
2777 video_stream->GetConfig();
2778 EXPECT_EQ(video_stream_config.rtp.local_ssrc,
2779 flexfec_stream_config.local_ssrc);
2780 EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
2781 EXPECT_EQ(video_stream_config.rtcp_send_transport,
2782 flexfec_stream_config.rtcp_send_transport);
2783 // TODO(brandtr): Update this EXPECT when we set |transport_cc| in a
2784 // spec-compliant way.
2785 EXPECT_EQ(video_stream_config.rtp.transport_cc,
2786 flexfec_stream_config.transport_cc);
2787 EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
2788 EXPECT_EQ(video_stream_config.rtp.extensions,
2789 flexfec_stream_config.rtp_header_extensions);
brandtr9c3d4c42017-01-23 06:59:13 -08002790}
2791
brandtr31bd2242017-05-19 05:47:46 -07002792// We should not send FlexFEC, even if we advertise it, unless the right
2793// field trial is set.
2794// TODO(brandtr): Remove when FlexFEC is enabled by default.
eladalonf1841382017-06-12 01:16:46 -07002795TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07002796 SetSendCodecsWithoutSsrcWithFecDoesNotEnableFec) {
2797 cricket::VideoSendParameters parameters;
2798 parameters.codecs.push_back(GetEngineCodec("VP8"));
2799 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2800 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2801
2802 FakeVideoSendStream* stream = AddSendStream();
2803 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2804
2805 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
2806 EXPECT_EQ(0, config.rtp.flexfec.ssrc);
2807 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
2808}
2809
eladalonf1841382017-06-12 01:16:46 -07002810TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07002811 SetSendCodecsWithSsrcWithFecDoesNotEnableFec) {
2812 cricket::VideoSendParameters parameters;
2813 parameters.codecs.push_back(GetEngineCodec("VP8"));
2814 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2815 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2816
2817 FakeVideoSendStream* stream = AddSendStream(
2818 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2819 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2820
2821 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
2822 EXPECT_EQ(0, config.rtp.flexfec.ssrc);
2823 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
2824}
2825
eladalonf1841382017-06-12 01:16:46 -07002826TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002827 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
magjed509e4fe2016-11-18 01:34:11 -08002828 const int kUnusedPayloadType = 127;
2829 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType));
2830
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002831 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002832 cricket::VideoCodec rtx_codec(kUnusedPayloadType, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002833 parameters.codecs.push_back(rtx_codec);
2834 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002835 << "RTX codec without associated payload type should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002836}
2837
eladalonf1841382017-06-12 01:16:46 -07002838TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002839 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
magjed509e4fe2016-11-18 01:34:11 -08002840 const int kUnusedPayloadType1 = 126;
2841 const int kUnusedPayloadType2 = 127;
2842 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
2843 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
2844 {
2845 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
2846 kUnusedPayloadType1, GetEngineCodec("VP8").id);
2847 cricket::VideoSendParameters parameters;
2848 parameters.codecs.push_back(GetEngineCodec("VP8"));
2849 parameters.codecs.push_back(rtx_codec);
2850 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2851 }
2852 {
2853 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
2854 kUnusedPayloadType1, kUnusedPayloadType2);
2855 cricket::VideoSendParameters parameters;
2856 parameters.codecs.push_back(GetEngineCodec("VP8"));
2857 parameters.codecs.push_back(rtx_codec);
2858 EXPECT_FALSE(channel_->SetSendParameters(parameters))
2859 << "RTX without matching video codec should be rejected.";
2860 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002861}
2862
eladalonf1841382017-06-12 01:16:46 -07002863TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithChangedRtxPayloadType) {
brandtr14742122017-01-27 04:53:07 -08002864 const int kUnusedPayloadType1 = 126;
2865 const int kUnusedPayloadType2 = 127;
2866 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
2867 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
2868
2869 // SSRCs for RTX.
2870 cricket::StreamParams params =
2871 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2872 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
2873 AddSendStream(params);
2874
2875 // Original payload type for RTX.
2876 cricket::VideoSendParameters parameters;
2877 parameters.codecs.push_back(GetEngineCodec("VP8"));
2878 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
2879 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
2880 parameters.codecs.push_back(rtx_codec);
2881 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2882 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
2883 const webrtc::VideoSendStream::Config& config_before =
2884 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2885 EXPECT_EQ(kUnusedPayloadType1, config_before.rtp.rtx.payload_type);
2886 ASSERT_EQ(1U, config_before.rtp.rtx.ssrcs.size());
2887 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx.ssrcs[0]);
2888
2889 // Change payload type for RTX.
2890 parameters.codecs[1].id = kUnusedPayloadType2;
2891 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2892 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
2893 const webrtc::VideoSendStream::Config& config_after =
2894 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2895 EXPECT_EQ(kUnusedPayloadType2, config_after.rtp.rtx.payload_type);
2896 ASSERT_EQ(1U, config_after.rtp.rtx.ssrcs.size());
2897 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx.ssrcs[0]);
2898}
2899
eladalonf1841382017-06-12 01:16:46 -07002900TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002901 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002902 parameters.codecs.push_back(GetEngineCodec("VP8"));
2903 parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002904 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002905
2906 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07002907 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002908
magjed509e4fe2016-11-18 01:34:11 -08002909 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002910
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002911 parameters.codecs.pop_back();
2912 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002913 stream = fake_call_->GetVideoSendStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08002914 ASSERT_TRUE(stream != nullptr);
perkj26091b12016-09-01 01:17:40 -07002915 config = stream->GetConfig().Copy();
brandtrb5f2c3f2016-10-04 23:28:39 -07002916 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08002917 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
2918}
2919
eladalonf1841382017-06-12 01:16:46 -07002920TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07002921 SetSendCodecsWithoutFecDisablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08002922 cricket::VideoSendParameters parameters;
2923 parameters.codecs.push_back(GetEngineCodec("VP8"));
2924 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
2925 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2926
2927 FakeVideoSendStream* stream = AddSendStream(
2928 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
2929 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
2930
brandtr3d200bd2017-01-16 06:59:19 -08002931 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
2932 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
brandtr468da7c2016-11-22 02:16:47 -08002933 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
2934 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
2935
2936 parameters.codecs.pop_back();
2937 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2938 stream = fake_call_->GetVideoSendStreams()[0];
2939 ASSERT_TRUE(stream != nullptr);
2940 config = stream->GetConfig().Copy();
brandtr3d200bd2017-01-16 06:59:19 -08002941 EXPECT_EQ(-1, config.rtp.flexfec.payload_type)
brandtr468da7c2016-11-22 02:16:47 -08002942 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002943}
2944
eladalonf1841382017-06-12 01:16:46 -07002945TEST_F(WebRtcVideoChannelTest, SetSendCodecsChangesExistingStreams) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002946 cricket::VideoSendParameters parameters;
perkj26752742016-10-24 01:21:16 -07002947 cricket::VideoCodec codec(100, "VP8");
2948 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax);
2949 parameters.codecs.push_back(codec);
perkjfa10b552016-10-02 23:45:26 -07002950
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002951 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002952 channel_->SetSend(true);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002953
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002954 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002955 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002956 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002957
2958 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07002959 EXPECT_EQ(kDefaultQpMax, streams[0].max_qp);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002960
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002961 parameters.codecs.clear();
perkj26752742016-10-24 01:21:16 -07002962 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax + 1);
2963 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002964 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002965 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07002966 EXPECT_EQ(kDefaultQpMax + 1, streams[0].max_qp);
deadbeef5a4a75a2016-06-02 16:23:38 -07002967 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002968}
2969
eladalonf1841382017-06-12 01:16:46 -07002970TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitrates) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002971 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
2972 200000);
2973}
2974
eladalonf1841382017-06-12 01:16:46 -07002975TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithHighMaxBitrate) {
pbos@webrtc.orga5f6fb52015-03-23 22:29:39 +00002976 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
2977 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
2978 ASSERT_EQ(1u, streams.size());
2979 EXPECT_EQ(10000000, streams[0].max_bitrate_bps);
2980}
2981
eladalonf1841382017-06-12 01:16:46 -07002982TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org00873182014-11-25 14:03:34 +00002983 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
2984 SetSendCodecsShouldWorkForBitrates(
2985 "", 0, "", -1, "", -1);
2986}
2987
eladalonf1841382017-06-12 01:16:46 -07002988TEST_F(WebRtcVideoChannelTest, SetSendCodecsCapsMinAndStartBitrate) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00002989 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002990}
2991
eladalonf1841382017-06-12 01:16:46 -07002992TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectsMaxLessThanMinBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002993 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "300";
2994 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "200";
2995 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002996}
2997
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07002998// Test that when both the codec-specific bitrate params and max_bandwidth_bps
2999// are present in the same send parameters, the settings are combined correctly.
eladalonf1841382017-06-12 01:16:46 -07003000TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitratesAndMaxSendBandwidth) {
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003001 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
3002 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
3003 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
3004 send_parameters_.max_bandwidth_bps = 400000;
3005 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3006 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
3007 EXPECT_EQ(200000, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
3008 // We expect max_bandwidth_bps to take priority, if set.
3009 EXPECT_EQ(400000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
3010
3011 // Decrease max_bandwidth_bps.
3012 send_parameters_.max_bandwidth_bps = 350000;
3013 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3014 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
3015 // Since the codec isn't changing, start_bitrate_bps should be -1.
3016 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
3017 EXPECT_EQ(350000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
3018
3019 // Now try again with the values flipped around.
3020 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
3021 send_parameters_.max_bandwidth_bps = 300000;
3022 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3023 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
3024 EXPECT_EQ(200000, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
3025 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
3026
3027 // If we change the codec max, max_bandwidth_bps should still apply.
3028 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
3029 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3030 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
3031 EXPECT_EQ(200000, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
3032 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
3033}
3034
eladalonf1841382017-06-12 01:16:46 -07003035TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org00873182014-11-25 14:03:34 +00003036 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
3037 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
3038 200000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003039 send_parameters_.max_bandwidth_bps = 300000;
3040 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01003041 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00003042 << "Setting max bitrate should keep previous min bitrate.";
Stefan Holmere5904162015-03-26 11:11:06 +01003043 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.start_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00003044 << "Setting max bitrate should not reset start bitrate.";
Stefan Holmere5904162015-03-26 11:11:06 +01003045 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00003046}
3047
eladalonf1841382017-06-12 01:16:46 -07003048TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldBeRemovable) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003049 send_parameters_.max_bandwidth_bps = 300000;
3050 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01003051 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos5c7760a2017-03-10 11:23:12 -08003052 // -1 means to disable max bitrate (set infinite).
3053 send_parameters_.max_bandwidth_bps = -1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003054 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01003055 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.max_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00003056 << "Setting zero max bitrate did not reset start bitrate.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003057}
3058
eladalonf1841382017-06-12 01:16:46 -07003059TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthAndAddSendStream) {
perkjfa10b552016-10-02 23:45:26 -07003060 send_parameters_.max_bandwidth_bps = 99999;
3061 FakeVideoSendStream* stream = AddSendStream();
3062 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
3063 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
3064 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
3065 ASSERT_EQ(1u, stream->GetVideoStreams().size());
3066 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
3067 stream->GetVideoStreams()[0].max_bitrate_bps);
3068
3069 send_parameters_.max_bandwidth_bps = 77777;
3070 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
3071 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
3072 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
3073 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
3074 stream->GetVideoStreams()[0].max_bitrate_bps);
3075}
3076
eladalonf1841382017-06-12 01:16:46 -07003077TEST_F(WebRtcVideoChannelTest, SetMaxSendBitrateCanIncreaseSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003078 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003079 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003080 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01003081 channel_->SetSend(true);
3082
3083 FakeVideoSendStream* stream = AddSendStream();
3084
Peter Boström3afc8c42016-01-27 16:45:21 +01003085 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07003086 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Peter Boström3afc8c42016-01-27 16:45:21 +01003087 EXPECT_EQ(cricket::CS_RUNNING,
3088 capturer.Start(capturer.GetSupportedFormats()->front()));
3089
Peter Boströmdfd53fe2015-03-27 15:58:11 +01003090 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
3091 int initial_max_bitrate_bps = streams[0].max_bitrate_bps;
3092 EXPECT_GT(initial_max_bitrate_bps, 0);
3093
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003094 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
3095 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01003096 // Insert a frame to update the encoder config.
3097 EXPECT_TRUE(capturer.CaptureFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01003098 streams = stream->GetVideoStreams();
3099 EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps);
deadbeef5a4a75a2016-06-02 16:23:38 -07003100 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01003101}
3102
eladalonf1841382017-06-12 01:16:46 -07003103TEST_F(WebRtcVideoChannelTest,
Peter Boströmdfd53fe2015-03-27 15:58:11 +01003104 SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003105 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003106 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003107 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01003108 channel_->SetSend(true);
3109
3110 FakeVideoSendStream* stream = AddSendStream(
3111 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
3112
3113 // Send a frame to make sure this scales up to >1 stream (simulcast).
3114 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07003115 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], true, nullptr, &capturer));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01003116 EXPECT_EQ(cricket::CS_RUNNING,
3117 capturer.Start(capturer.GetSupportedFormats()->front()));
3118 EXPECT_TRUE(capturer.CaptureFrame());
3119
3120 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
3121 ASSERT_GT(streams.size(), 1u)
3122 << "Without simulcast this test doesn't make sense.";
pbosbe16f792015-10-16 12:49:39 -07003123 int initial_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01003124 EXPECT_GT(initial_max_bitrate_bps, 0);
3125
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003126 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
3127 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01003128 // Insert a frame to update the encoder config.
3129 EXPECT_TRUE(capturer.CaptureFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01003130 streams = stream->GetVideoStreams();
pbosbe16f792015-10-16 12:49:39 -07003131 int increased_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01003132 EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps);
3133
deadbeef5a4a75a2016-06-02 16:23:38 -07003134 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], true, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01003135}
3136
eladalonf1841382017-06-12 01:16:46 -07003137TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithMaxQuantization) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003138 static const char* kMaxQuantization = "21";
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003139 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003140 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003141 parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
3142 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00003143 EXPECT_EQ(static_cast<unsigned int>(atoi(kMaxQuantization)),
3144 AddSendStream()->GetVideoStreams().back().max_qp);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003145
3146 VideoCodec codec;
3147 EXPECT_TRUE(channel_->GetSendCodec(&codec));
3148 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
3149}
3150
eladalonf1841382017-06-12 01:16:46 -07003151TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectBadPayloadTypes) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003152 // TODO(pbos): Should we only allow the dynamic range?
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00003153 static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003154 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003155 parameters.codecs.push_back(GetEngineCodec("VP8"));
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00003156 for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003157 parameters.codecs[0].id = kIncorrectPayloads[i];
3158 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pkasting@chromium.orgd3245462015-02-23 21:28:22 +00003159 << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003160 }
3161}
3162
eladalonf1841382017-06-12 01:16:46 -07003163TEST_F(WebRtcVideoChannelTest, SetSendCodecsAcceptAllValidPayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003164 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003165 parameters.codecs.push_back(GetEngineCodec("VP8"));
magjedf823ede2016-11-12 09:53:04 -08003166 for (int payload_type = 96; payload_type <= 127; ++payload_type) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003167 parameters.codecs[0].id = payload_type;
3168 EXPECT_TRUE(channel_->SetSendParameters(parameters))
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003169 << "Payload type '" << payload_type << "' rejected.";
3170 }
3171}
3172
deadbeef67cf2c12016-04-13 10:07:16 -07003173// Test that setting the a different set of codecs but with an identical front
3174// codec doesn't result in the stream being recreated.
3175// This may happen when a subsequent negotiation includes fewer codecs, as a
3176// result of one of the codecs being rejected.
eladalonf1841382017-06-12 01:16:46 -07003177TEST_F(WebRtcVideoChannelTest,
deadbeef67cf2c12016-04-13 10:07:16 -07003178 SetSendCodecsIdenticalFirstCodecDoesntRecreateStream) {
3179 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08003180 parameters1.codecs.push_back(GetEngineCodec("VP8"));
3181 parameters1.codecs.push_back(GetEngineCodec("VP9"));
deadbeef67cf2c12016-04-13 10:07:16 -07003182 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
3183
3184 AddSendStream();
3185 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
3186
3187 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08003188 parameters2.codecs.push_back(GetEngineCodec("VP8"));
deadbeef67cf2c12016-04-13 10:07:16 -07003189 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
3190 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
3191}
3192
eladalonf1841382017-06-12 01:16:46 -07003193TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithOnlyVp8) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003194 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003195 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003196 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003197}
3198
pbos@webrtc.orge322a172014-06-13 11:47:28 +00003199// Test that we set our inbound RTX codecs properly.
eladalonf1841382017-06-12 01:16:46 -07003200TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithRtx) {
magjed509e4fe2016-11-18 01:34:11 -08003201 const int kUnusedPayloadType1 = 126;
3202 const int kUnusedPayloadType2 = 127;
3203 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
3204 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
3205
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003206 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003207 parameters.codecs.push_back(GetEngineCodec("VP8"));
3208 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003209 parameters.codecs.push_back(rtx_codec);
3210 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00003211 << "RTX codec without associated payload should be rejected.";
3212
magjed509e4fe2016-11-18 01:34:11 -08003213 parameters.codecs[1].SetParam("apt", kUnusedPayloadType2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003214 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00003215 << "RTX codec with invalid associated payload type should be rejected.";
3216
magjed509e4fe2016-11-18 01:34:11 -08003217 parameters.codecs[1].SetParam("apt", GetEngineCodec("VP8").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003218 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orge322a172014-06-13 11:47:28 +00003219
magjed509e4fe2016-11-18 01:34:11 -08003220 cricket::VideoCodec rtx_codec2(kUnusedPayloadType2, "rtx");
pbos@webrtc.orge322a172014-06-13 11:47:28 +00003221 rtx_codec2.SetParam("apt", rtx_codec.id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003222 parameters.codecs.push_back(rtx_codec2);
pbos@webrtc.orge322a172014-06-13 11:47:28 +00003223
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003224 EXPECT_FALSE(channel_->SetRecvParameters(parameters)) <<
3225 "RTX codec with another RTX as associated payload type should be "
3226 "rejected.";
pbos@webrtc.orge322a172014-06-13 11:47:28 +00003227}
3228
eladalonf1841382017-06-12 01:16:46 -07003229TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithChangedRtxPayloadType) {
brandtr14742122017-01-27 04:53:07 -08003230 const int kUnusedPayloadType1 = 126;
3231 const int kUnusedPayloadType2 = 127;
3232 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
3233 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
3234
3235 // SSRCs for RTX.
3236 cricket::StreamParams params =
3237 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
3238 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
3239 AddRecvStream(params);
3240
3241 // Original payload type for RTX.
3242 cricket::VideoRecvParameters parameters;
3243 parameters.codecs.push_back(GetEngineCodec("VP8"));
3244 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
3245 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
3246 parameters.codecs.push_back(rtx_codec);
3247 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
3248 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
3249 const webrtc::VideoReceiveStream::Config& config_before =
3250 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
nisse26e3abb2017-08-25 04:44:25 -07003251 EXPECT_EQ(1U, config_before.rtp.rtx_associated_payload_types.size());
3252 const int* payload_type_before = FindKeyByValue(
3253 config_before.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
3254 ASSERT_NE(payload_type_before, nullptr);
3255 EXPECT_EQ(kUnusedPayloadType1, *payload_type_before);
brandtr14742122017-01-27 04:53:07 -08003256 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx_ssrc);
3257
3258 // Change payload type for RTX.
3259 parameters.codecs[1].id = kUnusedPayloadType2;
3260 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
3261 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
3262 const webrtc::VideoReceiveStream::Config& config_after =
3263 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
nisse26e3abb2017-08-25 04:44:25 -07003264 EXPECT_EQ(1U, config_after.rtp.rtx_associated_payload_types.size());
3265 const int* payload_type_after = FindKeyByValue(
3266 config_after.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
3267 ASSERT_NE(payload_type_after, nullptr);
3268 EXPECT_EQ(kUnusedPayloadType2, *payload_type_after);
brandtr14742122017-01-27 04:53:07 -08003269 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx_ssrc);
3270}
3271
eladalonf1841382017-06-12 01:16:46 -07003272TEST_F(WebRtcVideoChannelTest, SetRecvCodecsDifferentPayloadType) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003273 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003274 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003275 parameters.codecs[0].id = 99;
3276 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003277}
3278
eladalonf1841382017-06-12 01:16:46 -07003279TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptDefaultCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003280 cricket::VideoRecvParameters parameters;
3281 parameters.codecs = engine_.codecs();
3282 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00003283
3284 FakeVideoReceiveStream* stream = AddRecvStream();
Tommi733b5472016-06-10 17:58:01 +02003285 const webrtc::VideoReceiveStream::Config& config = stream->GetConfig();
pbos@webrtc.org776e6f22014-10-29 15:28:39 +00003286 EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].payload_name);
3287 EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003288}
3289
eladalonf1841382017-06-12 01:16:46 -07003290TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectUnsupportedCodec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003291 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003292 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj26752742016-10-24 01:21:16 -07003293 parameters.codecs.push_back(VideoCodec(101, "WTF3"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003294 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003295}
3296
eladalonf1841382017-06-12 01:16:46 -07003297TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptsMultipleVideoCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003298 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003299 parameters.codecs.push_back(GetEngineCodec("VP8"));
3300 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003301 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003302}
3303
eladalonf1841382017-06-12 01:16:46 -07003304TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003305 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08003306 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
3307 send_parameters.codecs.push_back(GetEngineCodec("red"));
3308 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003309 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00003310
3311 FakeVideoReceiveStream* stream = AddRecvStream();
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00003312
magjed509e4fe2016-11-18 01:34:11 -08003313 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07003314 stream->GetConfig().rtp.ulpfec_payload_type);
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00003315
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003316 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08003317 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003318 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003319 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08003320 ASSERT_TRUE(stream != nullptr);
nisse3b3622f2017-09-26 02:49:21 -07003321 EXPECT_EQ(-1, stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08003322 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
3323}
3324
eladalonf1841382017-06-12 01:16:46 -07003325TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvParamsWithoutFecDisablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08003326 AddRecvStream(
3327 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08003328 const std::vector<FakeFlexfecReceiveStream*>& streams =
brandtr468da7c2016-11-22 02:16:47 -08003329 fake_call_->GetFlexfecReceiveStreams();
3330
3331 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08003332 const FakeFlexfecReceiveStream* stream = streams.front();
3333 EXPECT_EQ(GetEngineCodec("flexfec-03").id, stream->GetConfig().payload_type);
3334 EXPECT_EQ(kFlexfecSsrc, stream->GetConfig().remote_ssrc);
3335 ASSERT_EQ(1U, stream->GetConfig().protected_media_ssrcs.size());
3336 EXPECT_EQ(kSsrcs1[0], stream->GetConfig().protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08003337
3338 cricket::VideoRecvParameters recv_parameters;
3339 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3340 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3341 EXPECT_TRUE(streams.empty())
3342 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003343}
3344
eladalonf1841382017-06-12 01:16:46 -07003345TEST_F(WebRtcVideoChannelTest, SetSendParamsWithFecEnablesFec) {
Stefan Holmer2b1f6512016-05-17 16:33:30 +02003346 FakeVideoReceiveStream* stream = AddRecvStream();
magjed509e4fe2016-11-18 01:34:11 -08003347 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07003348 stream->GetConfig().rtp.ulpfec_payload_type);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02003349
3350 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08003351 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3352 recv_parameters.codecs.push_back(GetEngineCodec("red"));
3353 recv_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02003354 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3355 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08003356 ASSERT_TRUE(stream != nullptr);
magjed509e4fe2016-11-18 01:34:11 -08003357 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07003358 stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08003359 << "ULPFEC should be enabled on the receive stream.";
Stefan Holmer2b1f6512016-05-17 16:33:30 +02003360
3361 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08003362 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
3363 send_parameters.codecs.push_back(GetEngineCodec("red"));
3364 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02003365 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
3366 stream = fake_call_->GetVideoReceiveStreams()[0];
magjed509e4fe2016-11-18 01:34:11 -08003367 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07003368 stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08003369 << "ULPFEC should be enabled on the receive stream.";
3370}
3371
eladalonf1841382017-06-12 01:16:46 -07003372TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07003373 SetSendRecvParamsWithFecEnablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08003374 AddRecvStream(
3375 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08003376 const std::vector<FakeFlexfecReceiveStream*>& streams =
brandtr468da7c2016-11-22 02:16:47 -08003377 fake_call_->GetFlexfecReceiveStreams();
3378
3379 cricket::VideoRecvParameters recv_parameters;
3380 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3381 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3382 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3383 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08003384 const FakeFlexfecReceiveStream* stream_with_recv_params = streams.front();
brandtr468da7c2016-11-22 02:16:47 -08003385 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9c3d4c42017-01-23 06:59:13 -08003386 stream_with_recv_params->GetConfig().payload_type);
3387 EXPECT_EQ(kFlexfecSsrc, stream_with_recv_params->GetConfig().remote_ssrc);
brandtr468da7c2016-11-22 02:16:47 -08003388 EXPECT_EQ(1U,
brandtr9c3d4c42017-01-23 06:59:13 -08003389 stream_with_recv_params->GetConfig().protected_media_ssrcs.size());
brandtr468da7c2016-11-22 02:16:47 -08003390 EXPECT_EQ(kSsrcs1[0],
brandtr9c3d4c42017-01-23 06:59:13 -08003391 stream_with_recv_params->GetConfig().protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08003392
3393 cricket::VideoSendParameters send_parameters;
3394 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
3395 send_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3396 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
3397 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08003398 const FakeFlexfecReceiveStream* stream_with_send_params = streams.front();
brandtr468da7c2016-11-22 02:16:47 -08003399 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9c3d4c42017-01-23 06:59:13 -08003400 stream_with_send_params->GetConfig().payload_type);
3401 EXPECT_EQ(kFlexfecSsrc, stream_with_send_params->GetConfig().remote_ssrc);
brandtr468da7c2016-11-22 02:16:47 -08003402 EXPECT_EQ(1U,
brandtr9c3d4c42017-01-23 06:59:13 -08003403 stream_with_send_params->GetConfig().protected_media_ssrcs.size());
brandtr468da7c2016-11-22 02:16:47 -08003404 EXPECT_EQ(kSsrcs1[0],
brandtr9c3d4c42017-01-23 06:59:13 -08003405 stream_with_send_params->GetConfig().protected_media_ssrcs[0]);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02003406}
3407
eladalonf1841382017-06-12 01:16:46 -07003408TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateFecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003409 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003410 parameters.codecs.push_back(GetEngineCodec("VP8"));
3411 parameters.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003412 parameters.codecs[1].id = parameters.codecs[0].id;
3413 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003414}
3415
eladalonf1841382017-06-12 01:16:46 -07003416TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07003417 SetRecvCodecsRejectDuplicateFecPayloads) {
brandtr468da7c2016-11-22 02:16:47 -08003418 cricket::VideoRecvParameters parameters;
3419 parameters.codecs.push_back(GetEngineCodec("VP8"));
3420 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3421 parameters.codecs[1].id = parameters.codecs[0].id;
3422 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
3423}
3424
eladalonf1841382017-06-12 01:16:46 -07003425TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateCodecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003426 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003427 parameters.codecs.push_back(GetEngineCodec("VP8"));
3428 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003429 parameters.codecs[1].id = parameters.codecs[0].id;
3430 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003431}
3432
eladalonf1841382017-06-12 01:16:46 -07003433TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003434 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003435 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003436 parameters.codecs.push_back(GetEngineCodec("VP8"));
3437 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003438 parameters.codecs[1].id += 1;
3439 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003440}
3441
deadbeef67cf2c12016-04-13 10:07:16 -07003442// Test that setting the same codecs but with a different order
deadbeef874ca3a2015-08-20 17:19:20 -07003443// doesn't result in the stream being recreated.
eladalonf1841382017-06-12 01:16:46 -07003444TEST_F(WebRtcVideoChannelTest,
deadbeef67cf2c12016-04-13 10:07:16 -07003445 SetRecvCodecsDifferentOrderDoesntRecreateStream) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003446 cricket::VideoRecvParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08003447 parameters1.codecs.push_back(GetEngineCodec("VP8"));
3448 parameters1.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003449 EXPECT_TRUE(channel_->SetRecvParameters(parameters1));
deadbeef874ca3a2015-08-20 17:19:20 -07003450
3451 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
3452 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
3453
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003454 cricket::VideoRecvParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08003455 parameters2.codecs.push_back(GetEngineCodec("red"));
3456 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003457 EXPECT_TRUE(channel_->SetRecvParameters(parameters2));
deadbeef874ca3a2015-08-20 17:19:20 -07003458 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
3459}
3460
eladalonf1841382017-06-12 01:16:46 -07003461TEST_F(WebRtcVideoChannelTest, SendStreamNotSendingByDefault) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003462 EXPECT_FALSE(AddSendStream()->IsSending());
3463}
3464
eladalonf1841382017-06-12 01:16:46 -07003465TEST_F(WebRtcVideoChannelTest, ReceiveStreamReceivingByDefault) {
pbos@webrtc.org85f42942014-07-22 09:14:58 +00003466 EXPECT_TRUE(AddRecvStream()->IsReceiving());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003467}
3468
eladalonf1841382017-06-12 01:16:46 -07003469TEST_F(WebRtcVideoChannelTest, SetSend) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +00003470 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003471 EXPECT_FALSE(stream->IsSending());
3472
3473 // false->true
3474 EXPECT_TRUE(channel_->SetSend(true));
3475 EXPECT_TRUE(stream->IsSending());
3476 // true->true
3477 EXPECT_TRUE(channel_->SetSend(true));
3478 EXPECT_TRUE(stream->IsSending());
3479 // true->false
3480 EXPECT_TRUE(channel_->SetSend(false));
3481 EXPECT_FALSE(stream->IsSending());
3482 // false->false
3483 EXPECT_TRUE(channel_->SetSend(false));
3484 EXPECT_FALSE(stream->IsSending());
3485
3486 EXPECT_TRUE(channel_->SetSend(true));
3487 FakeVideoSendStream* new_stream = AddSendStream();
3488 EXPECT_TRUE(new_stream->IsSending())
3489 << "Send stream created after SetSend(true) not sending initially.";
3490}
3491
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00003492// This test verifies DSCP settings are properly applied on video media channel.
eladalonf1841382017-06-12 01:16:46 -07003493TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
kwiberg686a8ef2016-02-26 03:00:35 -08003494 std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00003495 new cricket::FakeNetworkInterface);
nisse51542be2016-02-12 02:27:06 -08003496 MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08003497 std::unique_ptr<VideoMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08003498
3499 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
3500 channel->SetInterface(network_interface.get());
3501 // Default value when DSCP is disabled should be DSCP_DEFAULT.
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00003502 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
nisse51542be2016-02-12 02:27:06 -08003503
3504 config.enable_dscp = true;
3505 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
3506 channel->SetInterface(network_interface.get());
3507 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
3508
3509 // Verify that setting the option to false resets the
3510 // DiffServCodePoint.
3511 config.enable_dscp = false;
3512 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
3513 channel->SetInterface(network_interface.get());
3514 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003515}
3516
deadbeef13871492015-12-09 12:37:51 -08003517// This test verifies that the RTCP reduced size mode is properly applied to
3518// send video streams.
eladalonf1841382017-06-12 01:16:46 -07003519TEST_F(WebRtcVideoChannelTest, TestSetSendRtcpReducedSize) {
deadbeef13871492015-12-09 12:37:51 -08003520 // Create stream, expecting that default mode is "compound".
3521 FakeVideoSendStream* stream1 = AddSendStream();
3522 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
3523
3524 // Now enable reduced size mode.
3525 send_parameters_.rtcp.reduced_size = true;
3526 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3527 stream1 = fake_call_->GetVideoSendStreams()[0];
3528 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
3529
3530 // Create a new stream and ensure it picks up the reduced size mode.
3531 FakeVideoSendStream* stream2 = AddSendStream();
3532 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
3533}
3534
3535// This test verifies that the RTCP reduced size mode is properly applied to
3536// receive video streams.
eladalonf1841382017-06-12 01:16:46 -07003537TEST_F(WebRtcVideoChannelTest, TestSetRecvRtcpReducedSize) {
deadbeef13871492015-12-09 12:37:51 -08003538 // Create stream, expecting that default mode is "compound".
3539 FakeVideoReceiveStream* stream1 = AddRecvStream();
3540 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
3541
3542 // Now enable reduced size mode.
Taylor Brandstetter5f0b83b2016-03-18 15:02:07 -07003543 // TODO(deadbeef): Once "recv_parameters" becomes "receiver_parameters",
3544 // the reduced_size flag should come from that.
3545 send_parameters_.rtcp.reduced_size = true;
3546 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
deadbeef13871492015-12-09 12:37:51 -08003547 stream1 = fake_call_->GetVideoReceiveStreams()[0];
3548 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
3549
3550 // Create a new stream and ensure it picks up the reduced size mode.
3551 FakeVideoReceiveStream* stream2 = AddRecvStream();
3552 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
3553}
3554
eladalonf1841382017-06-12 01:16:46 -07003555TEST_F(WebRtcVideoChannelTest, OnReadyToSendSignalsNetworkState) {
skvlad7a43d252016-03-22 15:32:27 -07003556 EXPECT_EQ(webrtc::kNetworkUp,
3557 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
3558 EXPECT_EQ(webrtc::kNetworkUp,
3559 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003560
3561 channel_->OnReadyToSend(false);
skvlad7a43d252016-03-22 15:32:27 -07003562 EXPECT_EQ(webrtc::kNetworkDown,
3563 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
3564 EXPECT_EQ(webrtc::kNetworkUp,
3565 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003566
3567 channel_->OnReadyToSend(true);
skvlad7a43d252016-03-22 15:32:27 -07003568 EXPECT_EQ(webrtc::kNetworkUp,
3569 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
3570 EXPECT_EQ(webrtc::kNetworkUp,
3571 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003572}
3573
eladalonf1841382017-06-12 01:16:46 -07003574TEST_F(WebRtcVideoChannelTest, GetStatsReportsSentCodecName) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003575 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003576 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003577 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström74d9ed72015-03-26 16:28:31 +01003578
3579 AddSendStream();
3580
3581 cricket::VideoMediaInfo info;
3582 ASSERT_TRUE(channel_->GetStats(&info));
magjed509e4fe2016-11-18 01:34:11 -08003583 EXPECT_EQ("VP8", info.senders[0].codec_name);
Peter Boström74d9ed72015-03-26 16:28:31 +01003584}
3585
eladalonf1841382017-06-12 01:16:46 -07003586TEST_F(WebRtcVideoChannelTest, GetStatsReportsEncoderImplementationName) {
Peter Boströmb7d9a972015-12-18 16:01:11 +01003587 FakeVideoSendStream* stream = AddSendStream();
3588 webrtc::VideoSendStream::Stats stats;
3589 stats.encoder_implementation_name = "encoder_implementation_name";
3590 stream->SetStats(stats);
3591
3592 cricket::VideoMediaInfo info;
3593 ASSERT_TRUE(channel_->GetStats(&info));
3594 EXPECT_EQ(stats.encoder_implementation_name,
3595 info.senders[0].encoder_implementation_name);
3596}
3597
eladalonf1841382017-06-12 01:16:46 -07003598TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuOveruseMetrics) {
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00003599 FakeVideoSendStream* stream = AddSendStream();
3600 webrtc::VideoSendStream::Stats stats;
3601 stats.avg_encode_time_ms = 13;
3602 stats.encode_usage_percent = 42;
3603 stream->SetStats(stats);
3604
3605 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003606 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00003607 EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
3608 EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
3609}
3610
eladalonf1841382017-06-12 01:16:46 -07003611TEST_F(WebRtcVideoChannelTest, GetStatsReportsFramesEncoded) {
sakal43536c32016-10-24 01:46:43 -07003612 FakeVideoSendStream* stream = AddSendStream();
3613 webrtc::VideoSendStream::Stats stats;
3614 stats.frames_encoded = 13;
3615 stream->SetStats(stats);
3616
3617 cricket::VideoMediaInfo info;
3618 ASSERT_TRUE(channel_->GetStats(&info));
3619 EXPECT_EQ(stats.frames_encoded, info.senders[0].frames_encoded);
3620}
3621
eladalonf1841382017-06-12 01:16:46 -07003622TEST_F(WebRtcVideoChannelTest, GetStatsReportsQpSum) {
sakal87da4042016-10-31 06:53:47 -07003623 FakeVideoSendStream* stream = AddSendStream();
3624 webrtc::VideoSendStream::Stats stats;
3625 stats.qp_sum = rtc::Optional<uint64_t>(13);
3626 stream->SetStats(stats);
3627
3628 cricket::VideoMediaInfo info;
3629 ASSERT_TRUE(channel_->GetStats(&info));
3630 EXPECT_EQ(stats.qp_sum, info.senders[0].qp_sum);
3631}
3632
eladalonf1841382017-06-12 01:16:46 -07003633TEST_F(WebRtcVideoChannelTest, GetStatsReportsUpperResolution) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003634 FakeVideoSendStream* stream = AddSendStream();
3635 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003636 stats.substreams[17].width = 123;
3637 stats.substreams[17].height = 40;
3638 stats.substreams[42].width = 80;
3639 stats.substreams[42].height = 31;
3640 stats.substreams[11].width = 20;
3641 stats.substreams[11].height = 90;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003642 stream->SetStats(stats);
3643
3644 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003645 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org273a4142014-12-01 15:23:21 +00003646 ASSERT_EQ(1u, info.senders.size());
3647 EXPECT_EQ(123, info.senders[0].send_frame_width);
3648 EXPECT_EQ(90, info.senders[0].send_frame_height);
3649}
3650
eladalonf1841382017-06-12 01:16:46 -07003651TEST_F(WebRtcVideoChannelTest, GetStatsReportsPreferredBitrate) {
Pera48ddb72016-09-29 11:48:50 +02003652 FakeVideoSendStream* stream = AddSendStream();
3653 webrtc::VideoSendStream::Stats stats;
3654 stats.preferred_media_bitrate_bps = 5;
3655 stream->SetStats(stats);
3656
3657 cricket::VideoMediaInfo info;
3658 ASSERT_TRUE(channel_->GetStats(&info));
3659 ASSERT_EQ(1u, info.senders.size());
3660 EXPECT_EQ(5, info.senders[0].preferred_bitrate);
3661}
3662
eladalonf1841382017-06-12 01:16:46 -07003663TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuAdaptationStats) {
perkj803d97f2016-11-01 11:45:46 -07003664 FakeVideoSendStream* stream = AddSendStream();
3665 webrtc::VideoSendStream::Stats stats;
3666 stats.number_of_cpu_adapt_changes = 2;
3667 stats.cpu_limited_resolution = true;
3668 stream->SetStats(stats);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003669
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003670 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003671 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003672 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07003673 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU, info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07003674 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003675}
3676
eladalonf1841382017-06-12 01:16:46 -07003677TEST_F(WebRtcVideoChannelTest, GetStatsReportsAdaptationAndBandwidthStats) {
perkj803d97f2016-11-01 11:45:46 -07003678 FakeVideoSendStream* stream = AddSendStream();
asapersson17821db2015-12-14 02:08:12 -08003679 webrtc::VideoSendStream::Stats stats;
perkj803d97f2016-11-01 11:45:46 -07003680 stats.number_of_cpu_adapt_changes = 2;
3681 stats.cpu_limited_resolution = true;
asapersson17821db2015-12-14 02:08:12 -08003682 stats.bw_limited_resolution = true;
perkj803d97f2016-11-01 11:45:46 -07003683 stream->SetStats(stats);
3684
3685 cricket::VideoMediaInfo info;
asapersson17821db2015-12-14 02:08:12 -08003686 EXPECT_TRUE(channel_->GetStats(&info));
3687 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07003688 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU |
3689 WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08003690 info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07003691 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
asapersson17821db2015-12-14 02:08:12 -08003692}
3693
eladalonf1841382017-06-12 01:16:46 -07003694TEST_F(WebRtcVideoChannelTest,
asapersson17821db2015-12-14 02:08:12 -08003695 GetStatsTranslatesBandwidthLimitedResolutionCorrectly) {
3696 FakeVideoSendStream* stream = AddSendStream();
3697 webrtc::VideoSendStream::Stats stats;
3698 stats.bw_limited_resolution = true;
3699 stream->SetStats(stats);
3700
3701 cricket::VideoMediaInfo info;
3702 EXPECT_TRUE(channel_->GetStats(&info));
3703 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07003704 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08003705 info.senders[0].adapt_reason);
3706}
3707
eladalonf1841382017-06-12 01:16:46 -07003708TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003709 GetStatsTranslatesSendRtcpPacketTypesCorrectly) {
3710 FakeVideoSendStream* stream = AddSendStream();
3711 webrtc::VideoSendStream::Stats stats;
3712 stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2;
3713 stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3;
3714 stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4;
3715
3716 stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5;
3717 stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7;
3718 stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9;
3719
3720 stream->SetStats(stats);
3721
3722 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003723 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003724 EXPECT_EQ(7, info.senders[0].firs_rcvd);
3725 EXPECT_EQ(10, info.senders[0].nacks_rcvd);
3726 EXPECT_EQ(13, info.senders[0].plis_rcvd);
3727}
3728
eladalonf1841382017-06-12 01:16:46 -07003729TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003730 GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) {
3731 FakeVideoReceiveStream* stream = AddRecvStream();
3732 webrtc::VideoReceiveStream::Stats stats;
3733 stats.rtcp_packet_type_counts.fir_packets = 2;
3734 stats.rtcp_packet_type_counts.nack_packets = 3;
3735 stats.rtcp_packet_type_counts.pli_packets = 4;
3736 stream->SetStats(stats);
3737
3738 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003739 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003740 EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets,
3741 info.receivers[0].firs_sent);
3742 EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets,
3743 info.receivers[0].nacks_sent);
3744 EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets,
3745 info.receivers[0].plis_sent);
3746}
3747
eladalonf1841382017-06-12 01:16:46 -07003748TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesDecodeStatsCorrectly) {
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003749 FakeVideoReceiveStream* stream = AddRecvStream();
3750 webrtc::VideoReceiveStream::Stats stats;
Peter Boströmb7d9a972015-12-18 16:01:11 +01003751 stats.decoder_implementation_name = "decoder_implementation_name";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003752 stats.decode_ms = 2;
3753 stats.max_decode_ms = 3;
3754 stats.current_delay_ms = 4;
3755 stats.target_delay_ms = 5;
3756 stats.jitter_buffer_ms = 6;
3757 stats.min_playout_delay_ms = 7;
3758 stats.render_delay_ms = 8;
asapersson26dd92b2016-08-30 00:45:45 -07003759 stats.width = 9;
3760 stats.height = 10;
hbos42f6d2f2017-01-20 03:56:50 -08003761 stats.frame_counts.key_frames = 11;
3762 stats.frame_counts.delta_frames = 12;
hbos50cfe1f2017-01-23 07:21:55 -08003763 stats.frames_rendered = 13;
3764 stats.frames_decoded = 14;
sakalcc452e12017-02-09 04:53:45 -08003765 stats.qp_sum = rtc::Optional<uint64_t>(15);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003766 stream->SetStats(stats);
3767
3768 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003769 ASSERT_TRUE(channel_->GetStats(&info));
Peter Boströmb7d9a972015-12-18 16:01:11 +01003770 EXPECT_EQ(stats.decoder_implementation_name,
3771 info.receivers[0].decoder_implementation_name);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003772 EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
3773 EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
3774 EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
3775 EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
3776 EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
3777 EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
3778 EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
asapersson26dd92b2016-08-30 00:45:45 -07003779 EXPECT_EQ(stats.width, info.receivers[0].frame_width);
3780 EXPECT_EQ(stats.height, info.receivers[0].frame_height);
hbos42f6d2f2017-01-20 03:56:50 -08003781 EXPECT_EQ(stats.frame_counts.key_frames + stats.frame_counts.delta_frames,
3782 info.receivers[0].frames_received);
hbos50cfe1f2017-01-23 07:21:55 -08003783 EXPECT_EQ(stats.frames_rendered, info.receivers[0].frames_rendered);
sakale5ba44e2016-10-26 07:09:24 -07003784 EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded);
sakalcc452e12017-02-09 04:53:45 -08003785 EXPECT_EQ(stats.qp_sum, info.receivers[0].qp_sum);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003786}
3787
eladalonf1841382017-06-12 01:16:46 -07003788TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesReceivePacketStatsCorrectly) {
Peter Boström393347f2015-04-22 14:52:45 +02003789 FakeVideoReceiveStream* stream = AddRecvStream();
3790 webrtc::VideoReceiveStream::Stats stats;
3791 stats.rtp_stats.transmitted.payload_bytes = 2;
3792 stats.rtp_stats.transmitted.header_bytes = 3;
3793 stats.rtp_stats.transmitted.padding_bytes = 4;
3794 stats.rtp_stats.transmitted.packets = 5;
srte186d9c32017-08-04 05:03:53 -07003795 stats.rtcp_stats.packets_lost = 6;
Peter Boström393347f2015-04-22 14:52:45 +02003796 stats.rtcp_stats.fraction_lost = 7;
3797 stream->SetStats(stats);
3798
3799 cricket::VideoMediaInfo info;
3800 ASSERT_TRUE(channel_->GetStats(&info));
3801 EXPECT_EQ(stats.rtp_stats.transmitted.payload_bytes +
3802 stats.rtp_stats.transmitted.header_bytes +
3803 stats.rtp_stats.transmitted.padding_bytes,
3804 info.receivers[0].bytes_rcvd);
3805 EXPECT_EQ(stats.rtp_stats.transmitted.packets,
3806 info.receivers[0].packets_rcvd);
srte186d9c32017-08-04 05:03:53 -07003807 EXPECT_EQ(stats.rtcp_stats.packets_lost, info.receivers[0].packets_lost);
Peter Boström393347f2015-04-22 14:52:45 +02003808 EXPECT_EQ(static_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8),
3809 info.receivers[0].fraction_lost);
3810}
3811
eladalonf1841382017-06-12 01:16:46 -07003812TEST_F(WebRtcVideoChannelTest, TranslatesCallStatsCorrectly) {
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003813 AddSendStream();
3814 AddSendStream();
3815 webrtc::Call::Stats stats;
3816 stats.rtt_ms = 123;
3817 fake_call_->SetStats(stats);
3818
3819 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003820 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003821 ASSERT_EQ(2u, info.senders.size());
3822 EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms);
3823 EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
3824}
3825
eladalonf1841382017-06-12 01:16:46 -07003826TEST_F(WebRtcVideoChannelTest, TranslatesSenderBitrateStatsCorrectly) {
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003827 FakeVideoSendStream* stream = AddSendStream();
3828 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003829 stats.target_media_bitrate_bps = 156;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003830 stats.media_bitrate_bps = 123;
3831 stats.substreams[17].total_bitrate_bps = 1;
3832 stats.substreams[17].retransmit_bitrate_bps = 2;
3833 stats.substreams[42].total_bitrate_bps = 3;
3834 stats.substreams[42].retransmit_bitrate_bps = 4;
3835 stream->SetStats(stats);
3836
3837 FakeVideoSendStream* stream2 = AddSendStream();
3838 webrtc::VideoSendStream::Stats stats2;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003839 stats2.target_media_bitrate_bps = 200;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003840 stats2.media_bitrate_bps = 321;
3841 stats2.substreams[13].total_bitrate_bps = 5;
3842 stats2.substreams[13].retransmit_bitrate_bps = 6;
3843 stats2.substreams[21].total_bitrate_bps = 7;
3844 stats2.substreams[21].retransmit_bitrate_bps = 8;
3845 stream2->SetStats(stats2);
3846
3847 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003848 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003849 ASSERT_EQ(2u, info.senders.size());
stefanf79ade12017-06-02 06:44:03 -07003850 BandwidthEstimationInfo bwe_info;
3851 channel_->FillBitrateInfo(&bwe_info);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003852 // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
3853 // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
3854 EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate);
3855 EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate);
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003856 EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
stefanf79ade12017-06-02 06:44:03 -07003857 bwe_info.target_enc_bitrate);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003858 EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
stefanf79ade12017-06-02 06:44:03 -07003859 bwe_info.actual_enc_bitrate);
3860 EXPECT_EQ(1 + 3 + 5 + 7, bwe_info.transmit_bitrate)
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003861 << "Bandwidth stats should take all streams into account.";
stefanf79ade12017-06-02 06:44:03 -07003862 EXPECT_EQ(2 + 4 + 6 + 8, bwe_info.retransmit_bitrate)
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003863 << "Bandwidth stats should take all streams into account.";
3864}
3865
eladalonf1841382017-06-12 01:16:46 -07003866TEST_F(WebRtcVideoChannelTest, DefaultReceiveStreamReconfiguresToUseRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003867 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003868
Peter Boström0c4e06b2015-10-07 12:23:21 +02003869 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3870 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003871
3872 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
3873 const size_t kDataLength = 12;
3874 uint8_t data[kDataLength];
3875 memset(data, 0, sizeof(data));
3876 rtc::SetBE32(&data[8], ssrcs[0]);
jbaucheec21bd2016-03-20 06:15:43 -07003877 rtc::CopyOnWriteBuffer packet(data, kDataLength);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003878 rtc::PacketTime packet_time;
3879 channel_->OnPacketReceived(&packet, packet_time);
3880
3881 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
3882 << "No default receive stream created.";
3883 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr14742122017-01-27 04:53:07 -08003884 EXPECT_EQ(0u, recv_stream->GetConfig().rtp.rtx_ssrc)
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003885 << "Default receive stream should not have configured RTX";
3886
3887 EXPECT_TRUE(channel_->AddRecvStream(
3888 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
3889 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
brandtr14742122017-01-27 04:53:07 -08003890 << "AddRecvStream should have reconfigured, not added a new receiver.";
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003891 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
nisse26e3abb2017-08-25 04:44:25 -07003892 EXPECT_FALSE(
3893 recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
nisseca5706d2017-09-11 02:32:16 -07003894 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
Peter Boströmd8b01092016-05-12 16:44:36 +02003895 << "RTX should be mapped for all decoders/payload types.";
nisseca5706d2017-09-11 02:32:16 -07003896 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
3897 GetEngineCodec("red").id))
3898 << "RTX should be mapped also for the RED payload type";
brandtr14742122017-01-27 04:53:07 -08003899 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003900}
3901
eladalonf1841382017-06-12 01:16:46 -07003902TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithMissingSsrcsForRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003903 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd4362cd2015-03-25 14:17:23 +01003904
Peter Boström0c4e06b2015-10-07 12:23:21 +02003905 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3906 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd4362cd2015-03-25 14:17:23 +01003907
3908 StreamParams sp =
3909 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
3910 sp.ssrcs = ssrcs; // Without RTXs, this is the important part.
3911
3912 EXPECT_FALSE(channel_->AddSendStream(sp));
3913 EXPECT_FALSE(channel_->AddRecvStream(sp));
3914}
3915
eladalonf1841382017-06-12 01:16:46 -07003916TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithOverlappingRtxSsrcs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003917 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003918
Peter Boström0c4e06b2015-10-07 12:23:21 +02003919 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3920 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd6f4c252015-03-26 16:23:04 +01003921
3922 StreamParams sp =
3923 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
3924
3925 EXPECT_TRUE(channel_->AddSendStream(sp));
3926 EXPECT_TRUE(channel_->AddRecvStream(sp));
3927
3928 // The RTX SSRC is already used in previous streams, using it should fail.
3929 sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]);
3930 EXPECT_FALSE(channel_->AddSendStream(sp));
3931 EXPECT_FALSE(channel_->AddRecvStream(sp));
3932
3933 // After removing the original stream this should be fine to add (makes sure
3934 // that RTX ssrcs are not forever taken).
3935 EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0]));
3936 EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0]));
3937 EXPECT_TRUE(channel_->AddSendStream(sp));
3938 EXPECT_TRUE(channel_->AddRecvStream(sp));
3939}
3940
eladalonf1841382017-06-12 01:16:46 -07003941TEST_F(WebRtcVideoChannelTest,
Peter Boströmd6f4c252015-03-26 16:23:04 +01003942 RejectsAddingStreamsWithOverlappingSimulcastSsrcs) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003943 static const uint32_t kFirstStreamSsrcs[] = {1, 2, 3};
3944 static const uint32_t kOverlappingStreamSsrcs[] = {4, 3, 5};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003945 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003946
Peter Boströmd6f4c252015-03-26 16:23:04 +01003947 StreamParams sp =
3948 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs));
3949
3950 EXPECT_TRUE(channel_->AddSendStream(sp));
3951 EXPECT_TRUE(channel_->AddRecvStream(sp));
3952
3953 // One of the SSRCs is already used in previous streams, using it should fail.
3954 sp = cricket::CreateSimStreamParams("cname",
3955 MAKE_VECTOR(kOverlappingStreamSsrcs));
3956 EXPECT_FALSE(channel_->AddSendStream(sp));
3957 EXPECT_FALSE(channel_->AddRecvStream(sp));
3958
3959 // After removing the original stream this should be fine to add (makes sure
3960 // that RTX ssrcs are not forever taken).
Peter Boström3548dd22015-05-22 18:48:36 +02003961 EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0]));
3962 EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0]));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003963 EXPECT_TRUE(channel_->AddSendStream(sp));
3964 EXPECT_TRUE(channel_->AddRecvStream(sp));
3965}
3966
eladalonf1841382017-06-12 01:16:46 -07003967TEST_F(WebRtcVideoChannelTest, ReportsSsrcGroupsInStats) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003968 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström259bd202015-05-28 13:39:50 +02003969
3970 static const uint32_t kSenderSsrcs[] = {4, 7, 10};
3971 static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11};
3972
3973 StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams(
3974 "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs));
3975
3976 EXPECT_TRUE(channel_->AddSendStream(sender_sp));
3977
3978 static const uint32_t kReceiverSsrcs[] = {3};
3979 static const uint32_t kReceiverRtxSsrcs[] = {2};
3980
3981 StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams(
3982 "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs));
3983 EXPECT_TRUE(channel_->AddRecvStream(receiver_sp));
3984
3985 cricket::VideoMediaInfo info;
3986 ASSERT_TRUE(channel_->GetStats(&info));
3987
3988 ASSERT_EQ(1u, info.senders.size());
3989 ASSERT_EQ(1u, info.receivers.size());
3990
3991 EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups);
3992 EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups);
3993 EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
3994}
3995
eladalonf1841382017-06-12 01:16:46 -07003996TEST_F(WebRtcVideoChannelTest, MapsReceivedPayloadTypeToCodecName) {
pbosf42376c2015-08-28 07:35:32 -07003997 FakeVideoReceiveStream* stream = AddRecvStream();
3998 webrtc::VideoReceiveStream::Stats stats;
3999 cricket::VideoMediaInfo info;
4000
4001 // Report no codec name before receiving.
4002 stream->SetStats(stats);
4003 ASSERT_TRUE(channel_->GetStats(&info));
4004 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
4005
4006 // Report VP8 if we're receiving it.
magjed509e4fe2016-11-18 01:34:11 -08004007 stats.current_payload_type = GetEngineCodec("VP8").id;
pbosf42376c2015-08-28 07:35:32 -07004008 stream->SetStats(stats);
4009 ASSERT_TRUE(channel_->GetStats(&info));
4010 EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());
4011
4012 // Report no codec name for unknown playload types.
4013 stats.current_payload_type = 3;
4014 stream->SetStats(stats);
4015 ASSERT_TRUE(channel_->GetStats(&info));
4016 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
4017}
4018
eladalonf1841382017-06-12 01:16:46 -07004019void WebRtcVideoChannelTest::TestReceiveUnsignaledSsrcPacket(
noahricd10a68e2015-07-10 11:27:55 -07004020 uint8_t payload_type,
4021 bool expect_created_receive_stream) {
magjed509e4fe2016-11-18 01:34:11 -08004022 // kRedRtxPayloadType must currently be unused.
4023 EXPECT_FALSE(FindCodecById(engine_.codecs(), kRedRtxPayloadType));
4024
noahricd10a68e2015-07-10 11:27:55 -07004025 // Add a RED RTX codec.
4026 VideoCodec red_rtx_codec =
magjed509e4fe2016-11-18 01:34:11 -08004027 VideoCodec::CreateRtxCodec(kRedRtxPayloadType, GetEngineCodec("red").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004028 recv_parameters_.codecs.push_back(red_rtx_codec);
4029 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
noahricd10a68e2015-07-10 11:27:55 -07004030
4031 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
4032 const size_t kDataLength = 12;
4033 uint8_t data[kDataLength];
4034 memset(data, 0, sizeof(data));
4035
4036 rtc::Set8(data, 1, payload_type);
4037 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
jbaucheec21bd2016-03-20 06:15:43 -07004038 rtc::CopyOnWriteBuffer packet(data, kDataLength);
noahricd10a68e2015-07-10 11:27:55 -07004039 rtc::PacketTime packet_time;
4040 channel_->OnPacketReceived(&packet, packet_time);
4041
4042 if (expect_created_receive_stream) {
4043 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
4044 << "Should have created a receive stream for payload type: "
4045 << payload_type;
4046 } else {
4047 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size())
4048 << "Shouldn't have created a receive stream for payload type: "
4049 << payload_type;
4050 }
4051}
4052
eladalonf1841382017-06-12 01:16:46 -07004053TEST_F(WebRtcVideoChannelTest, Vp8PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08004054 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
4055 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07004056}
4057
eladalonf1841382017-06-12 01:16:46 -07004058TEST_F(WebRtcVideoChannelTest, Vp9PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08004059 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP9").id,
4060 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07004061}
4062
eladalonf1841382017-06-12 01:16:46 -07004063TEST_F(WebRtcVideoChannelTest, RtxPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08004064 const cricket::VideoCodec vp8 = GetEngineCodec("VP8");
4065 const int rtx_vp8_payload_type = default_apt_rtx_types_[vp8.id];
4066 TestReceiveUnsignaledSsrcPacket(rtx_vp8_payload_type,
4067 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07004068}
4069
eladalonf1841382017-06-12 01:16:46 -07004070TEST_F(WebRtcVideoChannelTest, UlpfecPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08004071 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("ulpfec").id,
4072 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07004073}
4074
eladalonf1841382017-06-12 01:16:46 -07004075TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr468da7c2016-11-22 02:16:47 -08004076 FlexfecPacketDoesntCreateUnsignalledStream) {
4077 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("flexfec-03").id,
4078 false /* expect_created_receive_stream */);
4079}
4080
eladalonf1841382017-06-12 01:16:46 -07004081TEST_F(WebRtcVideoChannelTest, RedRtxPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08004082 TestReceiveUnsignaledSsrcPacket(kRedRtxPayloadType,
4083 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07004084}
4085
mzanaty8a855d62017-02-17 15:46:43 -08004086// Test that receiving any unsignalled SSRC works even if it changes.
4087// The first unsignalled SSRC received will create a default receive stream.
4088// Any different unsignalled SSRC received will replace the default.
eladalonf1841382017-06-12 01:16:46 -07004089TEST_F(WebRtcVideoChannelTest, ReceiveDifferentUnsignaledSsrc) {
mzanaty8a855d62017-02-17 15:46:43 -08004090 // Allow receiving VP8, VP9, H264 (if enabled).
4091 cricket::VideoRecvParameters parameters;
4092 parameters.codecs.push_back(GetEngineCodec("VP8"));
4093 parameters.codecs.push_back(GetEngineCodec("VP9"));
4094
4095#if defined(WEBRTC_USE_H264)
4096 cricket::VideoCodec H264codec(126, "H264");
4097 parameters.codecs.push_back(H264codec);
4098#endif
4099
4100 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4101 // No receive streams yet.
4102 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
4103 cricket::FakeVideoRenderer renderer;
4104 EXPECT_TRUE(channel_->SetSink(kDefaultRecvSsrc, &renderer));
4105
4106 // Receive VP8 packet on first SSRC.
4107 uint8_t data[kMinRtpPacketLen];
4108 cricket::RtpHeader rtpHeader;
4109 rtpHeader.payload_type = GetEngineCodec("VP8").id;
4110 rtpHeader.seq_num = rtpHeader.timestamp = 0;
4111 rtpHeader.ssrc = kIncomingUnsignalledSsrc+1;
4112 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
4113 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
4114 rtc::PacketTime packet_time;
4115 channel_->OnPacketReceived(&packet, packet_time);
4116 // VP8 packet should create default receive stream.
4117 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
4118 FakeVideoReceiveStream* recv_stream =
4119 fake_call_->GetVideoReceiveStreams()[0];
4120 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
4121 // Verify that the receive stream sinks to a renderer.
4122 webrtc::VideoFrame video_frame(CreateBlackFrameBuffer(4, 4), 100, 0,
4123 webrtc::kVideoRotation_0);
4124 recv_stream->InjectFrame(video_frame);
4125 EXPECT_EQ(1, renderer.num_rendered_frames());
4126
4127 // Receive VP9 packet on second SSRC.
4128 rtpHeader.payload_type = GetEngineCodec("VP9").id;
4129 rtpHeader.ssrc = kIncomingUnsignalledSsrc+2;
4130 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
4131 rtc::CopyOnWriteBuffer packet2(data, sizeof(data));
4132 channel_->OnPacketReceived(&packet2, packet_time);
4133 // VP9 packet should replace the default receive SSRC.
4134 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
4135 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
4136 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
4137 // Verify that the receive stream sinks to a renderer.
4138 webrtc::VideoFrame video_frame2(CreateBlackFrameBuffer(4, 4), 200, 0,
ilnik00d802b2017-04-11 10:34:31 -07004139 webrtc::kVideoRotation_0);
mzanaty8a855d62017-02-17 15:46:43 -08004140 recv_stream->InjectFrame(video_frame2);
4141 EXPECT_EQ(2, renderer.num_rendered_frames());
4142
4143#if defined(WEBRTC_USE_H264)
4144 // Receive H264 packet on third SSRC.
4145 rtpHeader.payload_type = 126;
4146 rtpHeader.ssrc = kIncomingUnsignalledSsrc+3;
4147 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
4148 rtc::CopyOnWriteBuffer packet3(data, sizeof(data));
4149 channel_->OnPacketReceived(&packet3, packet_time);
4150 // H264 packet should replace the default receive SSRC.
4151 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
4152 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
4153 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
4154 // Verify that the receive stream sinks to a renderer.
4155 webrtc::VideoFrame video_frame3(CreateBlackFrameBuffer(4, 4), 300, 0,
ilnik00d802b2017-04-11 10:34:31 -07004156 webrtc::kVideoRotation_0);
mzanaty8a855d62017-02-17 15:46:43 -08004157 recv_stream->InjectFrame(video_frame3);
4158 EXPECT_EQ(3, renderer.num_rendered_frames());
4159#endif
4160}
4161
brandtr0dc57ea2017-05-29 23:33:31 -07004162// This test verifies that when a new default stream is created for a new
4163// unsignaled SSRC, the new stream does not overwrite any old stream that had
4164// been the default receive stream before being properly signaled.
eladalonf1841382017-06-12 01:16:46 -07004165TEST_F(WebRtcVideoChannelTest,
brandtr0dc57ea2017-05-29 23:33:31 -07004166 NewUnsignaledStreamDoesNotDestroyPreviouslyUnsignaledStream) {
4167 cricket::VideoRecvParameters parameters;
4168 parameters.codecs.push_back(GetEngineCodec("VP8"));
4169 ASSERT_TRUE(channel_->SetRecvParameters(parameters));
4170
4171 // No streams signaled and no packets received, so we should not have any
4172 // stream objects created yet.
4173 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
4174
4175 // Receive packet on an unsignaled SSRC.
4176 uint8_t data[kMinRtpPacketLen];
4177 cricket::RtpHeader rtp_header;
4178 rtp_header.payload_type = GetEngineCodec("VP8").id;
4179 rtp_header.seq_num = rtp_header.timestamp = 0;
4180 rtp_header.ssrc = kSsrcs3[0];
4181 cricket::SetRtpHeader(data, sizeof(data), rtp_header);
4182 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
4183 rtc::PacketTime packet_time;
4184 channel_->OnPacketReceived(&packet, packet_time);
4185 // Default receive stream should be created.
4186 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
4187 FakeVideoReceiveStream* recv_stream0 =
4188 fake_call_->GetVideoReceiveStreams()[0];
4189 EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);
4190
4191 // Signal the SSRC.
4192 EXPECT_TRUE(
4193 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs3[0])));
4194 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
4195 recv_stream0 = fake_call_->GetVideoReceiveStreams()[0];
4196 EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);
4197
4198 // Receive packet on a different unsignaled SSRC.
4199 rtp_header.ssrc = kSsrcs3[1];
4200 cricket::SetRtpHeader(data, sizeof(data), rtp_header);
4201 packet.SetData(data, sizeof(data));
4202 channel_->OnPacketReceived(&packet, packet_time);
4203 // New default receive stream should be created, but old stream should remain.
4204 ASSERT_EQ(2u, fake_call_->GetVideoReceiveStreams().size());
4205 EXPECT_EQ(recv_stream0, fake_call_->GetVideoReceiveStreams()[0]);
4206 FakeVideoReceiveStream* recv_stream1 =
4207 fake_call_->GetVideoReceiveStreams()[1];
4208 EXPECT_EQ(kSsrcs3[1], recv_stream1->GetConfig().rtp.remote_ssrc);
4209}
4210
eladalonf1841382017-06-12 01:16:46 -07004211TEST_F(WebRtcVideoChannelTest, CanSentMaxBitrateForExistingStream) {
skvladdc1c62c2016-03-16 19:07:43 -07004212 AddSendStream();
4213
4214 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07004215 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
skvladdc1c62c2016-03-16 19:07:43 -07004216 cricket::VideoFormat capture_format_hd =
4217 capturer.GetSupportedFormats()->front();
4218 EXPECT_EQ(1280, capture_format_hd.width);
4219 EXPECT_EQ(720, capture_format_hd.height);
4220 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
4221 EXPECT_TRUE(channel_->SetSend(true));
perkjfa10b552016-10-02 23:45:26 -07004222 capturer.CaptureFrame();
skvladdc1c62c2016-03-16 19:07:43 -07004223
perkjfa10b552016-10-02 23:45:26 -07004224 int default_encoder_bitrate = GetMaxEncoderBitrate();
brandtr468da7c2016-11-22 02:16:47 -08004225 EXPECT_GT(default_encoder_bitrate, 1000);
skvladdc1c62c2016-03-16 19:07:43 -07004226
4227 // TODO(skvlad): Resolve the inconsistency between the interpretation
4228 // of the global bitrate limit for audio and video:
4229 // - Audio: max_bandwidth_bps = 0 - fail the operation,
4230 // max_bandwidth_bps = -1 - remove the bandwidth limit
4231 // - Video: max_bandwidth_bps = 0 - remove the bandwidth limit,
pbos5c7760a2017-03-10 11:23:12 -08004232 // max_bandwidth_bps = -1 - remove the bandwidth limit
skvladdc1c62c2016-03-16 19:07:43 -07004233
perkjfa10b552016-10-02 23:45:26 -07004234 SetAndExpectMaxBitrate(1000, 0, 1000);
4235 SetAndExpectMaxBitrate(1000, 800, 800);
4236 SetAndExpectMaxBitrate(600, 800, 600);
4237 SetAndExpectMaxBitrate(0, 800, 800);
4238 SetAndExpectMaxBitrate(0, 0, default_encoder_bitrate);
skvladdc1c62c2016-03-16 19:07:43 -07004239
deadbeef5a4a75a2016-06-02 16:23:38 -07004240 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
skvladdc1c62c2016-03-16 19:07:43 -07004241}
4242
eladalonf1841382017-06-12 01:16:46 -07004243TEST_F(WebRtcVideoChannelTest, CannotSetMaxBitrateForNonexistentStream) {
skvladdc1c62c2016-03-16 19:07:43 -07004244 webrtc::RtpParameters nonexistent_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004245 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07004246 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
4247
4248 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004249 EXPECT_FALSE(
4250 channel_->SetRtpSendParameters(last_ssrc_, nonexistent_parameters));
skvladdc1c62c2016-03-16 19:07:43 -07004251}
4252
eladalonf1841382017-06-12 01:16:46 -07004253TEST_F(WebRtcVideoChannelTest,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004254 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvladdc1c62c2016-03-16 19:07:43 -07004255 // This test verifies that setting RtpParameters succeeds only if
4256 // the structure contains exactly one encoding.
deadbeefdbe2b872016-03-22 15:42:00 -07004257 // TODO(skvlad): Update this test when we start supporting setting parameters
skvladdc1c62c2016-03-16 19:07:43 -07004258 // for each encoding individually.
4259
4260 AddSendStream();
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004261 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07004262 // Two or more encodings should result in failure.
4263 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004264 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
deadbeeffb2aced2017-01-06 23:05:37 -08004265 // Zero encodings should also fail.
4266 parameters.encodings.clear();
4267 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
4268}
4269
4270// Changing the SSRC through RtpParameters is not allowed.
eladalonf1841382017-06-12 01:16:46 -07004271TEST_F(WebRtcVideoChannelTest, CannotSetSsrcInRtpSendParameters) {
deadbeeffb2aced2017-01-06 23:05:37 -08004272 AddSendStream();
4273 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
4274 parameters.encodings[0].ssrc = rtc::Optional<uint32_t>(0xdeadbeef);
4275 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07004276}
4277
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07004278// Test that a stream will not be sending if its encoding is made inactive
4279// through SetRtpSendParameters.
deadbeefdbe2b872016-03-22 15:42:00 -07004280// TODO(deadbeef): Update this test when we start supporting setting parameters
4281// for each encoding individually.
eladalonf1841382017-06-12 01:16:46 -07004282TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersEncodingsActive) {
deadbeefdbe2b872016-03-22 15:42:00 -07004283 FakeVideoSendStream* stream = AddSendStream();
4284 EXPECT_TRUE(channel_->SetSend(true));
4285 EXPECT_TRUE(stream->IsSending());
4286
4287 // Get current parameters and change "active" to false.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004288 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
deadbeefdbe2b872016-03-22 15:42:00 -07004289 ASSERT_EQ(1u, parameters.encodings.size());
4290 ASSERT_TRUE(parameters.encodings[0].active);
4291 parameters.encodings[0].active = false;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004292 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
deadbeefdbe2b872016-03-22 15:42:00 -07004293 EXPECT_FALSE(stream->IsSending());
4294
4295 // Now change it back to active and verify we resume sending.
4296 parameters.encodings[0].active = true;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004297 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
deadbeefdbe2b872016-03-22 15:42:00 -07004298 EXPECT_TRUE(stream->IsSending());
4299}
4300
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07004301// Test that if a stream is reconfigured (due to a codec change or other
4302// change) while its encoding is still inactive, it doesn't start sending.
eladalonf1841382017-06-12 01:16:46 -07004303TEST_F(WebRtcVideoChannelTest,
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07004304 InactiveStreamDoesntStartSendingWhenReconfigured) {
4305 // Set an initial codec list, which will be modified later.
4306 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08004307 parameters1.codecs.push_back(GetEngineCodec("VP8"));
4308 parameters1.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07004309 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
4310
4311 FakeVideoSendStream* stream = AddSendStream();
4312 EXPECT_TRUE(channel_->SetSend(true));
4313 EXPECT_TRUE(stream->IsSending());
4314
4315 // Get current parameters and change "active" to false.
4316 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
4317 ASSERT_EQ(1u, parameters.encodings.size());
4318 ASSERT_TRUE(parameters.encodings[0].active);
4319 parameters.encodings[0].active = false;
4320 EXPECT_EQ(1u, GetFakeSendStreams().size());
4321 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
4322 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
4323 EXPECT_FALSE(stream->IsSending());
4324
4325 // Reorder the codec list, causing the stream to be reconfigured.
4326 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08004327 parameters2.codecs.push_back(GetEngineCodec("VP9"));
4328 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07004329 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
4330 auto new_streams = GetFakeSendStreams();
4331 // Assert that a new underlying stream was created due to the codec change.
4332 // Otherwise, this test isn't testing what it set out to test.
4333 EXPECT_EQ(1u, GetFakeSendStreams().size());
4334 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
4335
4336 // Verify that we still are not sending anything, due to the inactive
4337 // encoding.
4338 EXPECT_FALSE(new_streams[0]->IsSending());
4339}
4340
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004341// Test that GetRtpSendParameters returns the currently configured codecs.
eladalonf1841382017-06-12 01:16:46 -07004342TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07004343 AddSendStream();
4344 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004345 parameters.codecs.push_back(GetEngineCodec("VP8"));
4346 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07004347 EXPECT_TRUE(channel_->SetSendParameters(parameters));
4348
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004349 webrtc::RtpParameters rtp_parameters =
4350 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07004351 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08004352 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
4353 rtp_parameters.codecs[0]);
4354 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
4355 rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07004356}
4357
deadbeeffb2aced2017-01-06 23:05:37 -08004358// Test that RtpParameters for send stream has one encoding and it has
4359// the correct SSRC.
eladalonf1841382017-06-12 01:16:46 -07004360TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersSsrc) {
deadbeeffb2aced2017-01-06 23:05:37 -08004361 AddSendStream();
4362
4363 webrtc::RtpParameters rtp_parameters =
4364 channel_->GetRtpSendParameters(last_ssrc_);
4365 ASSERT_EQ(1u, rtp_parameters.encodings.size());
4366 EXPECT_EQ(rtc::Optional<uint32_t>(last_ssrc_),
4367 rtp_parameters.encodings[0].ssrc);
4368}
4369
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07004370// Test that if we set/get parameters multiple times, we get the same results.
eladalonf1841382017-06-12 01:16:46 -07004371TEST_F(WebRtcVideoChannelTest, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07004372 AddSendStream();
4373 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004374 parameters.codecs.push_back(GetEngineCodec("VP8"));
4375 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07004376 EXPECT_TRUE(channel_->SetSendParameters(parameters));
4377
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004378 webrtc::RtpParameters initial_params =
4379 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07004380
4381 // We should be able to set the params we just got.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004382 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07004383
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004384 // ... And this shouldn't change the params returned by GetRtpSendParameters.
4385 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(last_ssrc_));
4386}
4387
4388// Test that GetRtpReceiveParameters returns the currently configured codecs.
eladalonf1841382017-06-12 01:16:46 -07004389TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersCodecs) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004390 AddRecvStream();
4391 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004392 parameters.codecs.push_back(GetEngineCodec("VP8"));
4393 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004394 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4395
4396 webrtc::RtpParameters rtp_parameters =
4397 channel_->GetRtpReceiveParameters(last_ssrc_);
4398 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08004399 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
4400 rtp_parameters.codecs[0]);
4401 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
4402 rtp_parameters.codecs[1]);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004403}
4404
johan073ece42016-08-26 02:59:47 -07004405#if defined(WEBRTC_USE_H264)
eladalonf1841382017-06-12 01:16:46 -07004406TEST_F(WebRtcVideoChannelTest, GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07004407#else
eladalonf1841382017-06-12 01:16:46 -07004408TEST_F(WebRtcVideoChannelTest, DISABLED_GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07004409#endif
johan3859c892016-08-05 09:19:25 -07004410 cricket::VideoRecvParameters parameters;
perkj26752742016-10-24 01:21:16 -07004411 cricket::VideoCodec kH264sprop1(101, "H264");
magjed5dfac562016-11-25 03:56:37 -08004412 kH264sprop1.SetParam(kH264FmtpSpropParameterSets, "uvw");
johan3859c892016-08-05 09:19:25 -07004413 parameters.codecs.push_back(kH264sprop1);
perkj26752742016-10-24 01:21:16 -07004414 cricket::VideoCodec kH264sprop2(102, "H264");
magjed5dfac562016-11-25 03:56:37 -08004415 kH264sprop2.SetParam(kH264FmtpSpropParameterSets, "xyz");
johan3859c892016-08-05 09:19:25 -07004416 parameters.codecs.push_back(kH264sprop2);
4417 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4418
4419 FakeVideoReceiveStream* recv_stream = AddRecvStream();
4420 const webrtc::VideoReceiveStream::Config& cfg = recv_stream->GetConfig();
4421 webrtc::RtpParameters rtp_parameters =
4422 channel_->GetRtpReceiveParameters(last_ssrc_);
4423 ASSERT_EQ(2u, rtp_parameters.codecs.size());
4424 EXPECT_EQ(kH264sprop1.ToCodecParameters(), rtp_parameters.codecs[0]);
4425 ASSERT_EQ(2u, cfg.decoders.size());
4426 EXPECT_EQ(101, cfg.decoders[0].payload_type);
4427 EXPECT_EQ("H264", cfg.decoders[0].payload_name);
magjed5dfac562016-11-25 03:56:37 -08004428 const auto it0 =
4429 cfg.decoders[0].codec_params.find(kH264FmtpSpropParameterSets);
4430 ASSERT_TRUE(it0 != cfg.decoders[0].codec_params.end());
4431 EXPECT_EQ("uvw", it0->second);
johan3859c892016-08-05 09:19:25 -07004432
4433 EXPECT_EQ(102, cfg.decoders[1].payload_type);
4434 EXPECT_EQ("H264", cfg.decoders[1].payload_name);
magjed5dfac562016-11-25 03:56:37 -08004435 const auto it1 =
4436 cfg.decoders[1].codec_params.find(kH264FmtpSpropParameterSets);
4437 ASSERT_TRUE(it1 != cfg.decoders[1].codec_params.end());
4438 EXPECT_EQ("xyz", it1->second);
johan3859c892016-08-05 09:19:25 -07004439}
4440
sakal1fd95952016-06-22 00:46:15 -07004441// Test that RtpParameters for receive stream has one encoding and it has
4442// the correct SSRC.
eladalonf1841382017-06-12 01:16:46 -07004443TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersSsrc) {
sakal1fd95952016-06-22 00:46:15 -07004444 AddRecvStream();
4445
4446 webrtc::RtpParameters rtp_parameters =
4447 channel_->GetRtpReceiveParameters(last_ssrc_);
4448 ASSERT_EQ(1u, rtp_parameters.encodings.size());
4449 EXPECT_EQ(rtc::Optional<uint32_t>(last_ssrc_),
4450 rtp_parameters.encodings[0].ssrc);
4451}
4452
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004453// Test that if we set/get parameters multiple times, we get the same results.
eladalonf1841382017-06-12 01:16:46 -07004454TEST_F(WebRtcVideoChannelTest, SetAndGetRtpReceiveParameters) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004455 AddRecvStream();
4456 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004457 parameters.codecs.push_back(GetEngineCodec("VP8"));
4458 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07004459 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4460
4461 webrtc::RtpParameters initial_params =
4462 channel_->GetRtpReceiveParameters(last_ssrc_);
4463
4464 // We should be able to set the params we just got.
4465 EXPECT_TRUE(channel_->SetRtpReceiveParameters(last_ssrc_, initial_params));
4466
4467 // ... And this shouldn't change the params returned by
4468 // GetRtpReceiveParameters.
4469 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(last_ssrc_));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07004470}
4471
deadbeef3bc15102017-04-20 19:25:07 -07004472// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
4473// aren't signaled. It should always return an empty "RtpEncodingParameters",
4474// even after a packet is received and the unsignaled SSRC is known.
eladalonf1841382017-06-12 01:16:46 -07004475TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersWithUnsignaledSsrc) {
deadbeef3bc15102017-04-20 19:25:07 -07004476 // Call necessary methods to configure receiving a default stream as
4477 // soon as it arrives.
4478 cricket::VideoRecvParameters parameters;
4479 parameters.codecs.push_back(GetEngineCodec("VP8"));
4480 parameters.codecs.push_back(GetEngineCodec("VP9"));
4481 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4482
4483 // Call GetRtpReceiveParameters before configured to receive an unsignaled
4484 // stream. Should return nothing.
4485 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
4486
4487 // Set a sink for an unsignaled stream.
4488 cricket::FakeVideoRenderer renderer;
4489 // Value of "0" means "unsignaled stream".
4490 EXPECT_TRUE(channel_->SetSink(0, &renderer));
4491
4492 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
4493 // in this method means "unsignaled stream".
4494 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
4495 ASSERT_EQ(1u, rtp_parameters.encodings.size());
4496 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
4497
4498 // Receive VP8 packet.
4499 uint8_t data[kMinRtpPacketLen];
4500 cricket::RtpHeader rtpHeader;
4501 rtpHeader.payload_type = GetEngineCodec("VP8").id;
4502 rtpHeader.seq_num = rtpHeader.timestamp = 0;
4503 rtpHeader.ssrc = kIncomingUnsignalledSsrc;
4504 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
4505 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
4506 rtc::PacketTime packet_time;
4507 channel_->OnPacketReceived(&packet, packet_time);
4508
4509 // The |ssrc| member should still be unset.
4510 rtp_parameters = channel_->GetRtpReceiveParameters(0);
4511 ASSERT_EQ(1u, rtp_parameters.encodings.size());
4512 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
4513}
4514
eladalonf1841382017-06-12 01:16:46 -07004515void WebRtcVideoChannelTest::TestReceiverLocalSsrcConfiguration(
Peter Boström3548dd22015-05-22 18:48:36 +02004516 bool receiver_first) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004517 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström3548dd22015-05-22 18:48:36 +02004518
4519 const uint32_t kSenderSsrc = 0xC0FFEE;
Peter Boströmdfa28152015-10-21 17:21:10 +02004520 const uint32_t kSecondSenderSsrc = 0xBADCAFE;
Peter Boström3548dd22015-05-22 18:48:36 +02004521 const uint32_t kReceiverSsrc = 0x4711;
Peter Boströmdfa28152015-10-21 17:21:10 +02004522 const uint32_t kExpectedDefaultReceiverSsrc = 1;
Peter Boström3548dd22015-05-22 18:48:36 +02004523
4524 if (receiver_first) {
4525 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
4526 std::vector<FakeVideoReceiveStream*> receive_streams =
4527 fake_call_->GetVideoReceiveStreams();
4528 ASSERT_EQ(1u, receive_streams.size());
Peter Boströmdfa28152015-10-21 17:21:10 +02004529 // Default local SSRC when we have no sender.
4530 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
4531 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02004532 }
4533 AddSendStream(StreamParams::CreateLegacy(kSenderSsrc));
4534 if (!receiver_first)
4535 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
4536 std::vector<FakeVideoReceiveStream*> receive_streams =
4537 fake_call_->GetVideoReceiveStreams();
4538 ASSERT_EQ(1u, receive_streams.size());
4539 EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boströmdfa28152015-10-21 17:21:10 +02004540
4541 // Removing first sender should fall back to another (in this case the second)
4542 // local send stream's SSRC.
4543 AddSendStream(StreamParams::CreateLegacy(kSecondSenderSsrc));
4544 ASSERT_TRUE(channel_->RemoveSendStream(kSenderSsrc));
4545 receive_streams =
4546 fake_call_->GetVideoReceiveStreams();
4547 ASSERT_EQ(1u, receive_streams.size());
4548 EXPECT_EQ(kSecondSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
4549
4550 // Removing the last sender should fall back to default local SSRC.
4551 ASSERT_TRUE(channel_->RemoveSendStream(kSecondSenderSsrc));
4552 receive_streams =
4553 fake_call_->GetVideoReceiveStreams();
4554 ASSERT_EQ(1u, receive_streams.size());
4555 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
4556 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02004557}
4558
eladalonf1841382017-06-12 01:16:46 -07004559TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrc) {
Peter Boström3548dd22015-05-22 18:48:36 +02004560 TestReceiverLocalSsrcConfiguration(false);
4561}
4562
eladalonf1841382017-06-12 01:16:46 -07004563TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrcOnExistingReceivers) {
Peter Boström3548dd22015-05-22 18:48:36 +02004564 TestReceiverLocalSsrcConfiguration(true);
4565}
4566
eladalonf1841382017-06-12 01:16:46 -07004567class WebRtcVideoChannelSimulcastTest : public testing::Test {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004568 public:
eladalonf1841382017-06-12 01:16:46 -07004569 WebRtcVideoChannelSimulcastTest()
magjed2475ae22017-09-12 04:42:15 -07004570 : fake_call_(webrtc::Call::Config(&event_log_)),
Magnus Jedvert02e7a192017-09-23 17:21:32 +02004571 encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
4572 decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
4573 engine_(std::unique_ptr<cricket::WebRtcVideoEncoderFactory>(
4574 encoder_factory_),
4575 std::unique_ptr<cricket::WebRtcVideoDecoderFactory>(
4576 decoder_factory_)),
magjed2475ae22017-09-12 04:42:15 -07004577 last_ssrc_(0) {}
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004578
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00004579 void SetUp() override {
nisse51542be2016-02-12 02:27:06 -08004580 channel_.reset(
kthelgason2bc68642017-02-07 07:02:22 -08004581 engine_.CreateChannel(&fake_call_, GetMediaConfig(), VideoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08004582 channel_->OnReadyToSend(true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004583 last_ssrc_ = 123;
4584 }
4585
4586 protected:
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004587 void VerifySimulcastSettings(const VideoCodec& codec,
perkj26752742016-10-24 01:21:16 -07004588 int capture_width,
4589 int capture_height,
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004590 size_t num_configured_streams,
sprang429600d2017-01-26 06:12:26 -08004591 size_t expected_num_streams,
4592 bool screenshare,
4593 bool conference_mode) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004594 cricket::VideoSendParameters parameters;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004595 parameters.codecs.push_back(codec);
sprang429600d2017-01-26 06:12:26 -08004596 parameters.conference_mode = conference_mode;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004597 ASSERT_TRUE(channel_->SetSendParameters(parameters));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004598
Peter Boström0c4e06b2015-10-07 12:23:21 +02004599 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
henrikg91d6ede2015-09-17 00:24:34 -07004600 RTC_DCHECK(num_configured_streams <= ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004601 ssrcs.resize(num_configured_streams);
4602
sprangf24a0642017-02-28 13:23:26 -08004603 AddSendStream(CreateSimStreamParams("cname", ssrcs));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00004604 // Send a full-size frame to trigger a stream reconfiguration to use all
4605 // expected simulcast layers.
4606 cricket::FakeVideoCapturer capturer;
sprangf24a0642017-02-28 13:23:26 -08004607 VideoOptions options;
4608 if (screenshare)
4609 options.is_screencast = rtc::Optional<bool>(screenshare);
deadbeef5a4a75a2016-06-02 16:23:38 -07004610 EXPECT_TRUE(
sprang429600d2017-01-26 06:12:26 -08004611 channel_->SetVideoSend(ssrcs.front(), true, &options, &capturer));
sprangf24a0642017-02-28 13:23:26 -08004612 // Fetch the latest stream since SetVideoSend() may recreate it if the
4613 // screen content setting is changed.
4614 FakeVideoSendStream* stream = fake_call_.GetVideoSendStreams().front();
pbos@webrtc.org86196c42015-02-16 21:02:00 +00004615 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(cricket::VideoFormat(
perkj26752742016-10-24 01:21:16 -07004616 capture_width, capture_height,
pbos@webrtc.org86196c42015-02-16 21:02:00 +00004617 cricket::VideoFormat::FpsToInterval(30),
4618 cricket::FOURCC_I420)));
4619 channel_->SetSend(true);
4620 EXPECT_TRUE(capturer.CaptureFrame());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004621
4622 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
4623 ASSERT_EQ(expected_num_streams, video_streams.size());
4624
sprang429600d2017-01-26 06:12:26 -08004625 std::vector<webrtc::VideoStream> expected_streams;
4626 if (conference_mode) {
4627 expected_streams = GetSimulcastConfig(
4628 num_configured_streams, capture_width, capture_height, 0,
4629 kDefaultQpMax, kDefaultVideoMaxFramerate, screenshare);
sprang3ebabf12017-02-16 07:35:22 -08004630 if (screenshare) {
4631 for (const webrtc::VideoStream& stream : expected_streams) {
4632 // Never scale screen content.
4633 EXPECT_EQ(stream.width, capture_width);
4634 EXPECT_EQ(stream.height, capture_height);
4635 }
4636 }
sprang429600d2017-01-26 06:12:26 -08004637 } else {
4638 webrtc::VideoStream stream;
4639 stream.width = capture_width;
4640 stream.height = capture_height;
4641 stream.max_framerate = kDefaultVideoMaxFramerate;
4642 stream.min_bitrate_bps = cricket::kMinVideoBitrateKbps * 1000;
4643 int max_bitrate_kbps;
4644 if (capture_width * capture_height <= 320 * 240) {
4645 max_bitrate_kbps = 600;
4646 } else if (capture_width * capture_height <= 640 * 480) {
4647 max_bitrate_kbps = 1700;
4648 } else if (capture_width * capture_height <= 960 * 540) {
4649 max_bitrate_kbps = 2000;
4650 } else {
4651 max_bitrate_kbps = 2500;
4652 }
4653 stream.target_bitrate_bps = stream.max_bitrate_bps =
4654 max_bitrate_kbps * 1000;
4655 stream.max_qp = kDefaultQpMax;
4656 expected_streams.push_back(stream);
4657 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004658
4659 ASSERT_EQ(expected_streams.size(), video_streams.size());
4660
4661 size_t num_streams = video_streams.size();
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004662 int total_max_bitrate_bps = 0;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004663 for (size_t i = 0; i < num_streams; ++i) {
4664 EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
4665 EXPECT_EQ(expected_streams[i].height, video_streams[i].height);
4666
4667 EXPECT_GT(video_streams[i].max_framerate, 0);
4668 EXPECT_EQ(expected_streams[i].max_framerate,
4669 video_streams[i].max_framerate);
4670
4671 EXPECT_GT(video_streams[i].min_bitrate_bps, 0);
4672 EXPECT_EQ(expected_streams[i].min_bitrate_bps,
4673 video_streams[i].min_bitrate_bps);
4674
4675 EXPECT_GT(video_streams[i].target_bitrate_bps, 0);
4676 EXPECT_EQ(expected_streams[i].target_bitrate_bps,
4677 video_streams[i].target_bitrate_bps);
4678
4679 EXPECT_GT(video_streams[i].max_bitrate_bps, 0);
4680 EXPECT_EQ(expected_streams[i].max_bitrate_bps,
4681 video_streams[i].max_bitrate_bps);
4682
4683 EXPECT_GT(video_streams[i].max_qp, 0);
4684 EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp);
4685
sprang429600d2017-01-26 06:12:26 -08004686 EXPECT_EQ(!conference_mode,
4687 expected_streams[i].temporal_layer_thresholds_bps.empty());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004688 EXPECT_EQ(expected_streams[i].temporal_layer_thresholds_bps,
4689 video_streams[i].temporal_layer_thresholds_bps);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004690
4691 if (i == num_streams - 1) {
4692 total_max_bitrate_bps += video_streams[i].max_bitrate_bps;
4693 } else {
4694 total_max_bitrate_bps += video_streams[i].target_bitrate_bps;
4695 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004696 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004697
deadbeef5a4a75a2016-06-02 16:23:38 -07004698 EXPECT_TRUE(channel_->SetVideoSend(ssrcs.front(), true, nullptr, nullptr));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004699 }
4700
4701 FakeVideoSendStream* AddSendStream() {
4702 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++));
4703 }
4704
4705 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
4706 size_t num_streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02004707 fake_call_.GetVideoSendStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004708 EXPECT_TRUE(channel_->AddSendStream(sp));
4709 std::vector<FakeVideoSendStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02004710 fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004711 EXPECT_EQ(num_streams + 1, streams.size());
4712 return streams[streams.size() - 1];
4713 }
4714
4715 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02004716 return fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004717 }
4718
4719 FakeVideoReceiveStream* AddRecvStream() {
4720 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++));
4721 }
4722
4723 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
4724 size_t num_streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02004725 fake_call_.GetVideoReceiveStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004726 EXPECT_TRUE(channel_->AddRecvStream(sp));
4727 std::vector<FakeVideoReceiveStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02004728 fake_call_.GetVideoReceiveStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004729 EXPECT_EQ(num_streams + 1, streams.size());
4730 return streams[streams.size() - 1];
4731 }
4732
skvlad11a9cbf2016-10-07 11:53:05 -07004733 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +02004734 FakeCall fake_call_;
Magnus Jedvert02e7a192017-09-23 17:21:32 +02004735 cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
4736 cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
eladalonf1841382017-06-12 01:16:46 -07004737 WebRtcVideoEngine engine_;
kwiberg686a8ef2016-02-26 03:00:35 -08004738 std::unique_ptr<VideoMediaChannel> channel_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02004739 uint32_t last_ssrc_;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004740};
4741
eladalonf1841382017-06-12 01:16:46 -07004742TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith2SimulcastStreams) {
sprang429600d2017-01-26 06:12:26 -08004743 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 640, 360, 2, 2, false,
4744 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004745}
4746
eladalonf1841382017-06-12 01:16:46 -07004747TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith3SimulcastStreams) {
sprang429600d2017-01-26 06:12:26 -08004748 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, false,
4749 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004750}
4751
4752// Test that we normalize send codec format size in simulcast.
eladalonf1841382017-06-12 01:16:46 -07004753TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
sprang429600d2017-01-26 06:12:26 -08004754 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 541, 271, 2, 2, false,
4755 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00004756}
sprang429600d2017-01-26 06:12:26 -08004757
eladalonf1841382017-06-12 01:16:46 -07004758TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForScreenshare) {
sprang429600d2017-01-26 06:12:26 -08004759 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
4760 false);
4761}
4762
eladalonf1841382017-06-12 01:16:46 -07004763TEST_F(WebRtcVideoChannelSimulcastTest,
sprang429600d2017-01-26 06:12:26 -08004764 SetSendCodecsForConferenceModeScreenshare) {
4765 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
4766 true);
4767}
4768
eladalonf1841382017-06-12 01:16:46 -07004769TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForSimulcastScreenshare) {
sprang429600d2017-01-26 06:12:26 -08004770 webrtc::test::ScopedFieldTrials override_field_trials_(
4771 "WebRTC-SimulcastScreenshare/Enabled/");
4772 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 2, true,
4773 true);
4774}
4775
eladalonf1841382017-06-12 01:16:46 -07004776TEST_F(WebRtcVideoChannelSimulcastTest,
sprangfe627f32017-03-29 08:24:59 -07004777 NoSimulcastScreenshareWithoutConference) {
4778 webrtc::test::ScopedFieldTrials override_field_trials_(
4779 "WebRTC-SimulcastScreenshare/Enabled/");
4780 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
4781 false);
4782}
4783
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004784} // namespace cricket