blob: 26b13ed3986d819110aaa1032458f6ea594bc672 [file] [log] [blame]
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00009 */
10
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +000011#include <algorithm>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000012#include <map>
kwiberg686a8ef2016-02-26 03:00:35 -080013#include <memory>
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000014#include <vector>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000015
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +000016#include "webrtc/base/arraysize.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000017#include "webrtc/base/gunit.h"
18#include "webrtc/base/stringutils.h"
kjellandera96e2d72016-02-04 23:52:28 -080019#include "webrtc/media/base/testutils.h"
20#include "webrtc/media/base/videoengine_unittest.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010021#include "webrtc/media/engine/fakewebrtccall.h"
22#include "webrtc/media/engine/fakewebrtcvideoengine.h"
23#include "webrtc/media/engine/simulcast.h"
24#include "webrtc/media/engine/webrtcvideochannelfactory.h"
25#include "webrtc/media/engine/webrtcvideoengine2.h"
26#include "webrtc/media/engine/webrtcvoiceengine.h"
stefanc1aeaf02015-10-15 07:26:07 -070027#include "webrtc/test/field_trial.h"
pbos@webrtc.org42684be2014-10-03 11:25:45 +000028#include "webrtc/video_encoder.h"
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000029
isheriff6f8d6862016-05-26 11:24:55 -070030using webrtc::RtpExtension;
31
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000032namespace {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000033static const int kDefaultQpMax = 56;
34static const int kDefaultFramerate = 30;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000035
deadbeef67cf2c12016-04-13 10:07:16 -070036static const cricket::VideoCodec kVp8Codec720p(100, "VP8", 1280, 720, 30);
37static const cricket::VideoCodec kVp8Codec360p(100, "VP8", 640, 360, 30);
38static const cricket::VideoCodec kVp8Codec270p(100, "VP8", 480, 270, 30);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000039
deadbeef67cf2c12016-04-13 10:07:16 -070040static const cricket::VideoCodec kVp8Codec(100, "VP8", 640, 400, 30);
41static const cricket::VideoCodec kVp9Codec(101, "VP9", 640, 400, 30);
42static const cricket::VideoCodec kH264Codec(102, "H264", 640, 400, 30);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +000043
deadbeef67cf2c12016-04-13 10:07:16 -070044static const cricket::VideoCodec kRedCodec(116, "red", 0, 0, 0);
45static const cricket::VideoCodec kUlpfecCodec(117, "ulpfec", 0, 0, 0);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000046
noahricd10a68e2015-07-10 11:27:55 -070047static const uint8_t kRedRtxPayloadType = 125;
48
Peter Boström0c4e06b2015-10-07 12:23:21 +020049static const uint32_t kSsrcs1[] = {1};
50static const uint32_t kSsrcs3[] = {1, 2, 3};
51static const uint32_t kRtxSsrcs1[] = {4};
52static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE;
pbos@webrtc.org3c107582014-07-20 15:27:35 +000053static const char kUnsupportedExtensionName[] =
54 "urn:ietf:params:rtp-hdrext:unsupported";
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000055
56void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) {
57 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
58 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
59 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
60 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
61 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
62 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
63 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
stefan43edf0f2015-11-20 18:05:48 -080064 cricket::kRtcpFbParamTransportCc, cricket::kParamValueEmpty)));
65 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000066 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
67}
68
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070069static void CreateBlackFrame(webrtc::VideoFrame* video_frame,
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +000070 int width,
71 int height) {
72 video_frame->CreateEmptyFrame(
73 width, height, width, (width + 1) / 2, (width + 1) / 2);
nissec9c142f2016-05-17 04:05:47 -070074 memset(video_frame->video_frame_buffer()->MutableDataY(), 16,
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +000075 video_frame->allocated_size(webrtc::kYPlane));
nissec9c142f2016-05-17 04:05:47 -070076 memset(video_frame->video_frame_buffer()->MutableDataU(), 128,
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +000077 video_frame->allocated_size(webrtc::kUPlane));
nissec9c142f2016-05-17 04:05:47 -070078 memset(video_frame->video_frame_buffer()->MutableDataV(), 128,
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +000079 video_frame->allocated_size(webrtc::kVPlane));
80}
81
Shao Changbine62202f2015-04-21 20:24:50 +080082void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config,
83 const std::map<int, int>& rtx_types) {
84 std::map<int, int>::const_iterator it;
85 it = rtx_types.find(config.encoder_settings.payload_type);
86 EXPECT_TRUE(it != rtx_types.end() &&
87 it->second == config.rtp.rtx.payload_type);
88
89 if (config.rtp.fec.red_rtx_payload_type != -1) {
90 it = rtx_types.find(config.rtp.fec.red_payload_type);
91 EXPECT_TRUE(it != rtx_types.end() &&
92 it->second == config.rtp.fec.red_rtx_payload_type);
93 }
94}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000095} // namespace
96
97namespace cricket {
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +000098class WebRtcVideoEngine2Test : public ::testing::Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000099 public:
stefanc1aeaf02015-10-15 07:26:07 -0700100 WebRtcVideoEngine2Test() : WebRtcVideoEngine2Test("") {}
101 explicit WebRtcVideoEngine2Test(const char* field_trials)
stefanc1aeaf02015-10-15 07:26:07 -0700102 : override_field_trials_(field_trials),
103 call_(webrtc::Call::Create(webrtc::Call::Config())),
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200104 engine_() {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000105 std::vector<VideoCodec> engine_codecs = engine_.codecs();
henrikg91d6ede2015-09-17 00:24:34 -0700106 RTC_DCHECK(!engine_codecs.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000107 bool codec_set = false;
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000108 for (size_t i = 0; i < engine_codecs.size(); ++i) {
109 if (engine_codecs[i].name == "red") {
110 default_red_codec_ = engine_codecs[i];
111 } else if (engine_codecs[i].name == "ulpfec") {
112 default_ulpfec_codec_ = engine_codecs[i];
113 } else if (engine_codecs[i].name == "rtx") {
Shao Changbine62202f2015-04-21 20:24:50 +0800114 int associated_payload_type;
115 if (engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
116 &associated_payload_type)) {
117 default_apt_rtx_types_[associated_payload_type] = engine_codecs[i].id;
118 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000119 } else if (!codec_set) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000120 default_codec_ = engine_codecs[i];
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000121 codec_set = true;
122 }
123 }
124
henrikg91d6ede2015-09-17 00:24:34 -0700125 RTC_DCHECK(codec_set);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000126 }
127
128 protected:
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000129 VideoMediaChannel* SetUpForExternalEncoderFactory(
130 cricket::WebRtcVideoEncoderFactory* encoder_factory,
131 const std::vector<VideoCodec>& codecs);
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000132
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000133 VideoMediaChannel* SetUpForExternalDecoderFactory(
134 cricket::WebRtcVideoDecoderFactory* decoder_factory,
135 const std::vector<VideoCodec>& codecs);
136
Peter Boströme4499152016-02-05 11:13:28 +0100137 void TestExtendedEncoderOveruse(bool use_external_encoder);
138
stefanc1aeaf02015-10-15 07:26:07 -0700139 webrtc::test::ScopedFieldTrials override_field_trials_;
pbos@webrtc.orgf1f0d9a2015-03-02 13:30:15 +0000140 // Used in WebRtcVideoEngine2VoiceTest, but defined here so it's properly
141 // initialized when the constructor is called.
kwiberg686a8ef2016-02-26 03:00:35 -0800142 std::unique_ptr<webrtc::Call> call_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000143 WebRtcVideoEngine2 engine_;
144 VideoCodec default_codec_;
145 VideoCodec default_red_codec_;
146 VideoCodec default_ulpfec_codec_;
Shao Changbine62202f2015-04-21 20:24:50 +0800147 std::map<int, int> default_apt_rtx_types_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000148};
149
Peter Boström12996152016-05-14 02:03:18 +0200150TEST_F(WebRtcVideoEngine2Test, AnnouncesVp9AccordingToBuildFlags) {
151 bool claims_vp9_support = false;
152 for (const cricket::VideoCodec& codec : engine_.codecs()) {
153 if (codec.name == "VP9") {
154 claims_vp9_support = true;
155 break;
156 }
157 }
158#if defined(RTC_DISABLE_VP9)
159 EXPECT_FALSE(claims_vp9_support);
160#else
161 EXPECT_TRUE(claims_vp9_support);
162#endif // defined(RTC_DISABLE_VP9)
163}
164
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000165TEST_F(WebRtcVideoEngine2Test, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
166 std::vector<VideoCodec> engine_codecs = engine_.codecs();
167 for (size_t i = 0; i < engine_codecs.size(); ++i) {
168 if (engine_codecs[i].name != kRtxCodecName)
169 continue;
170 int associated_payload_type;
171 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000172 &associated_payload_type));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000173 EXPECT_EQ(default_codec_.id, associated_payload_type);
174 return;
175 }
176 FAIL() << "No RTX codec found among default codecs.";
177}
178
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000179TEST_F(WebRtcVideoEngine2Test, SupportsTimestampOffsetHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100180 RtpCapabilities capabilities = engine_.GetCapabilities();
181 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700182 for (const RtpExtension& extension : capabilities.header_extensions) {
183 if (extension.uri == RtpExtension::kTimestampOffsetUri) {
184 EXPECT_EQ(RtpExtension::kTimestampOffsetDefaultId, extension.id);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000185 return;
186 }
187 }
188 FAIL() << "Timestamp offset extension not in header-extension list.";
189}
190
191TEST_F(WebRtcVideoEngine2Test, SupportsAbsoluteSenderTimeHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100192 RtpCapabilities capabilities = engine_.GetCapabilities();
193 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700194 for (const RtpExtension& extension : capabilities.header_extensions) {
195 if (extension.uri == RtpExtension::kAbsSendTimeUri) {
196 EXPECT_EQ(RtpExtension::kAbsSendTimeDefaultId, extension.id);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000197 return;
198 }
199 }
200 FAIL() << "Absolute Sender Time extension not in header-extension list.";
201}
202
stefanc1aeaf02015-10-15 07:26:07 -0700203class WebRtcVideoEngine2WithSendSideBweTest : public WebRtcVideoEngine2Test {
204 public:
205 WebRtcVideoEngine2WithSendSideBweTest()
206 : WebRtcVideoEngine2Test("WebRTC-SendSideBwe/Enabled/") {}
207};
208
209TEST_F(WebRtcVideoEngine2WithSendSideBweTest,
210 SupportsTransportSequenceNumberHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100211 RtpCapabilities capabilities = engine_.GetCapabilities();
212 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700213 for (const RtpExtension& extension : capabilities.header_extensions) {
214 if (extension.uri == RtpExtension::kTransportSequenceNumberUri) {
215 EXPECT_EQ(RtpExtension::kTransportSequenceNumberDefaultId, extension.id);
stefanc1aeaf02015-10-15 07:26:07 -0700216 return;
217 }
218 }
219 FAIL() << "Transport sequence number extension not in header-extension list.";
220}
221
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700222TEST_F(WebRtcVideoEngine2Test, SupportsVideoRotationHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100223 RtpCapabilities capabilities = engine_.GetCapabilities();
224 ASSERT_FALSE(capabilities.header_extensions.empty());
isheriff6f8d6862016-05-26 11:24:55 -0700225 for (const RtpExtension& extension : capabilities.header_extensions) {
226 if (extension.uri == RtpExtension::kVideoRotationUri) {
227 EXPECT_EQ(RtpExtension::kVideoRotationDefaultId, extension.id);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700228 return;
229 }
230 }
231 FAIL() << "Video Rotation extension not in header-extension list.";
232}
233
234TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionBeforeCapturer) {
235 // Allocate the capturer first to prevent early destruction before channel's
236 // dtor is called.
237 cricket::FakeVideoCapturer capturer;
238
239 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
240 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200241 cricket::VideoSendParameters parameters;
242 parameters.codecs.push_back(kVp8Codec);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700243
kwiberg686a8ef2016-02-26 03:00:35 -0800244 std::unique_ptr<VideoMediaChannel> channel(
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200245 SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700246 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
247
248 // Add CVO extension.
249 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200250 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700251 RtpExtension(RtpExtension::kVideoRotationUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200252 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700253
254 // Set capturer.
deadbeef5a4a75a2016-06-02 16:23:38 -0700255 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700256
257 // Verify capturer has turned off applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700258 EXPECT_FALSE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700259
260 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200261 parameters.extensions.clear();
262 EXPECT_TRUE(channel->SetSendParameters(parameters));
nisse47ac4622016-05-25 08:47:01 -0700263 EXPECT_TRUE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700264}
265
perkj91e1c152016-03-02 05:34:00 -0800266TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionBeforeAddSendStream) {
267 // Allocate the capturer first to prevent early destruction before channel's
268 // dtor is called.
269 cricket::FakeVideoCapturer capturer;
270
271 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
272 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
273 cricket::VideoSendParameters parameters;
274 parameters.codecs.push_back(kVp8Codec);
275
276 std::unique_ptr<VideoMediaChannel> channel(
277 SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs));
278 // Add CVO extension.
279 const int id = 1;
280 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700281 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkj91e1c152016-03-02 05:34:00 -0800282 EXPECT_TRUE(channel->SetSendParameters(parameters));
283 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
284
285 // Set capturer.
deadbeef5a4a75a2016-06-02 16:23:38 -0700286 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
perkj91e1c152016-03-02 05:34:00 -0800287
288 // Verify capturer has turned off applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700289 EXPECT_FALSE(capturer.apply_rotation());
perkj91e1c152016-03-02 05:34:00 -0800290}
291
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700292TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionAfterCapturer) {
293 cricket::FakeVideoCapturer capturer;
294
295 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
296 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
perkjcaafdba2016-03-20 07:34:29 -0700297 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP9, "VP9");
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200298 cricket::VideoSendParameters parameters;
299 parameters.codecs.push_back(kVp8Codec);
perkjcaafdba2016-03-20 07:34:29 -0700300 parameters.codecs.push_back(kVp9Codec);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700301
kwiberg686a8ef2016-02-26 03:00:35 -0800302 std::unique_ptr<VideoMediaChannel> channel(
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200303 SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700304 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
305
306 // Set capturer.
deadbeef5a4a75a2016-06-02 16:23:38 -0700307 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700308
perkjcaafdba2016-03-20 07:34:29 -0700309 // Verify capturer has turned on applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700310 EXPECT_TRUE(capturer.apply_rotation());
perkjcaafdba2016-03-20 07:34:29 -0700311
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700312 // Add CVO extension.
313 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200314 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700315 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkjcaafdba2016-03-20 07:34:29 -0700316 // Also remove the first codec to trigger a codec change as well.
317 parameters.codecs.erase(parameters.codecs.begin());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200318 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700319
320 // Verify capturer has turned off applying rotation.
nisse47ac4622016-05-25 08:47:01 -0700321 EXPECT_FALSE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700322
323 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200324 parameters.extensions.clear();
325 EXPECT_TRUE(channel->SetSendParameters(parameters));
nisse47ac4622016-05-25 08:47:01 -0700326 EXPECT_TRUE(capturer.apply_rotation());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700327}
328
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000329TEST_F(WebRtcVideoEngine2Test, SetSendFailsBeforeSettingCodecs) {
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200330 engine_.Init();
kwiberg686a8ef2016-02-26 03:00:35 -0800331 std::unique_ptr<VideoMediaChannel> channel(
nisse51542be2016-02-12 02:27:06 -0800332 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions()));
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000333
334 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
335
336 EXPECT_FALSE(channel->SetSend(true))
337 << "Channel should not start without codecs.";
338 EXPECT_TRUE(channel->SetSend(false))
339 << "Channel should be stoppable even without set codecs.";
340}
341
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000342TEST_F(WebRtcVideoEngine2Test, GetStatsWithoutSendCodecsSetDoesNotCrash) {
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200343 engine_.Init();
kwiberg686a8ef2016-02-26 03:00:35 -0800344 std::unique_ptr<VideoMediaChannel> channel(
nisse51542be2016-02-12 02:27:06 -0800345 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions()));
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000346 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
347 VideoMediaInfo info;
348 channel->GetStats(&info);
349}
350
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000351TEST_F(WebRtcVideoEngine2Test, UseExternalFactoryForVp8WhenSupported) {
352 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
353 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200354 cricket::VideoSendParameters parameters;
355 parameters.codecs.push_back(kVp8Codec);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000356
kwiberg686a8ef2016-02-26 03:00:35 -0800357 std::unique_ptr<VideoMediaChannel> channel(
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200358 SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000359
360 EXPECT_TRUE(
361 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
pbos14fe7082016-04-20 06:35:56 -0700362 ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(1));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000363 ASSERT_EQ(1u, encoder_factory.encoders().size());
364 EXPECT_TRUE(channel->SetSend(true));
365
366 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700367 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000368 EXPECT_EQ(cricket::CS_RUNNING,
369 capturer.Start(capturer.GetSupportedFormats()->front()));
370 EXPECT_TRUE(capturer.CaptureFrame());
pbos14fe7082016-04-20 06:35:56 -0700371 // Sending one frame will have reallocated the encoder since input size
372 // changes from a small default to the actual frame width/height. Wait for
373 // that to happen then for the frame to be sent.
374 ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(2));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000375 EXPECT_TRUE_WAIT(encoder_factory.encoders()[0]->GetNumEncodedFrames() > 0,
376 kTimeout);
377
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000378 int num_created_encoders = encoder_factory.GetNumCreatedEncoders();
379 EXPECT_EQ(num_created_encoders, 2);
380
381 // Setting codecs of the same type should not reallocate any encoders
382 // (expecting a no-op).
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200383 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000384 EXPECT_EQ(num_created_encoders, encoder_factory.GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000385
386 // Remove stream previously added to free the external encoder instance.
387 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
388 EXPECT_EQ(0u, encoder_factory.encoders().size());
389}
390
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700391// Test that when an external encoder factory supports a codec we don't
392// internally support, we still add an RTX codec for it.
393// TODO(deadbeef): Currently this test is only effective if WebRTC is
394// built with no internal H264 support. This test should be updated
395// if/when we start adding RTX codecs for unrecognized codec names.
396TEST_F(WebRtcVideoEngine2Test, RtxCodecAddedForExternalCodec) {
397 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
398 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
399 engine_.SetExternalEncoderFactory(&encoder_factory);
400 engine_.Init();
401
402 auto codecs = engine_.codecs();
403 // First figure out what payload type the test codec got assigned.
404 auto test_codec_it =
405 std::find_if(codecs.begin(), codecs.end(),
406 [](const VideoCodec& c) { return c.name == "H264"; });
407 ASSERT_NE(codecs.end(), test_codec_it);
408 // Now search for an RTX codec for it.
409 EXPECT_TRUE(std::any_of(codecs.begin(), codecs.end(),
410 [&test_codec_it](const VideoCodec& c) {
411 int associated_payload_type;
412 return c.name == "rtx" &&
413 c.GetParam(kCodecParamAssociatedPayloadType,
414 &associated_payload_type) &&
415 associated_payload_type == test_codec_it->id;
416 }));
417}
418
Peter Boströme4499152016-02-05 11:13:28 +0100419void WebRtcVideoEngine2Test::TestExtendedEncoderOveruse(
420 bool use_external_encoder) {
421 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
422 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
423 cricket::VideoSendParameters parameters;
424 parameters.codecs.push_back(kVp8Codec);
kwiberg686a8ef2016-02-26 03:00:35 -0800425 std::unique_ptr<VideoMediaChannel> channel;
Peter Boströme4499152016-02-05 11:13:28 +0100426 FakeCall* fake_call = new FakeCall(webrtc::Call::Config());
427 call_.reset(fake_call);
428 if (use_external_encoder) {
429 channel.reset(
430 SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs));
431 } else {
432 engine_.Init();
nisse51542be2016-02-12 02:27:06 -0800433 channel.reset(
434 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions()));
Peter Boströme4499152016-02-05 11:13:28 +0100435 }
436 ASSERT_TRUE(
437 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
438 EXPECT_TRUE(channel->SetSendParameters(parameters));
439 EXPECT_TRUE(channel->SetSend(true));
440 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
441
442 EXPECT_EQ(use_external_encoder,
443 stream->GetConfig().encoder_settings.full_overuse_time);
444 // Remove stream previously added to free the external encoder instance.
445 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
446}
447
448TEST_F(WebRtcVideoEngine2Test, EnablesFullEncoderTimeForExternalEncoders) {
449 TestExtendedEncoderOveruse(true);
450}
451
452TEST_F(WebRtcVideoEngine2Test, DisablesFullEncoderTimeForNonExternalEncoders) {
453 TestExtendedEncoderOveruse(false);
454}
455
Peter Boström12996152016-05-14 02:03:18 +0200456#if !defined(RTC_DISABLE_VP9)
Peter Boström53eda3d2015-03-27 15:53:18 +0100457TEST_F(WebRtcVideoEngine2Test, CanConstructDecoderForVp9EncoderFactory) {
458 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
459 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP9, "VP9");
460 std::vector<cricket::VideoCodec> codecs;
461 codecs.push_back(kVp9Codec);
462
kwiberg686a8ef2016-02-26 03:00:35 -0800463 std::unique_ptr<VideoMediaChannel> channel(
Peter Boström53eda3d2015-03-27 15:53:18 +0100464 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
465
466 EXPECT_TRUE(
467 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
468}
Peter Boström12996152016-05-14 02:03:18 +0200469#endif // !defined(RTC_DISABLE_VP9)
Peter Boström53eda3d2015-03-27 15:53:18 +0100470
qiangchenc27d89f2015-07-16 10:27:16 -0700471TEST_F(WebRtcVideoEngine2Test, PropagatesInputFrameTimestamp) {
472 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
473 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
474 std::vector<cricket::VideoCodec> codecs;
475 codecs.push_back(kVp8Codec);
476
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200477 FakeCall* fake_call = new FakeCall(webrtc::Call::Config());
478 call_.reset(fake_call);
kwiberg686a8ef2016-02-26 03:00:35 -0800479 std::unique_ptr<VideoMediaChannel> channel(
qiangchenc27d89f2015-07-16 10:27:16 -0700480 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
481
482 EXPECT_TRUE(
483 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
484
485 FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700486 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer));
qiangchenc27d89f2015-07-16 10:27:16 -0700487 capturer.Start(cricket::VideoFormat(1280, 720,
488 cricket::VideoFormat::FpsToInterval(60),
489 cricket::FOURCC_I420));
490 channel->SetSend(true);
491
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200492 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
qiangchenc27d89f2015-07-16 10:27:16 -0700493
494 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700495 int64_t last_timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700496 for (int i = 0; i < 10; i++) {
497 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700498 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700499 int64_t interval = timestamp - last_timestamp;
500
501 // Precision changes from nanosecond to millisecond.
502 // Allow error to be no more than 1.
503 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1);
504
505 last_timestamp = timestamp;
506 }
507
508 capturer.Start(cricket::VideoFormat(1280, 720,
509 cricket::VideoFormat::FpsToInterval(30),
510 cricket::FOURCC_I420));
511
512 EXPECT_TRUE(capturer.CaptureFrame());
513 last_timestamp = stream->GetLastTimestamp();
514 for (int i = 0; i < 10; i++) {
515 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700516 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700517 int64_t interval = timestamp - last_timestamp;
518
519 // Precision changes from nanosecond to millisecond.
520 // Allow error to be no more than 1.
521 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1);
522
523 last_timestamp = timestamp;
524 }
525
526 // Remove stream previously added to free the external encoder instance.
527 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
528}
529
pbos1cb121d2015-09-14 11:38:38 -0700530TEST_F(WebRtcVideoEngine2Test,
531 ProducesIncreasingTimestampsWithResetInputSources) {
532 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
533 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
534 std::vector<cricket::VideoCodec> codecs;
535 codecs.push_back(kVp8Codec);
536
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200537 FakeCall* fake_call = new FakeCall(webrtc::Call::Config());
538 call_.reset(fake_call);
kwiberg686a8ef2016-02-26 03:00:35 -0800539 std::unique_ptr<VideoMediaChannel> channel(
pbos1cb121d2015-09-14 11:38:38 -0700540 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
541
542 EXPECT_TRUE(
543 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
544 channel->SetSend(true);
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200545 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
pbos1cb121d2015-09-14 11:38:38 -0700546
547 FakeVideoCapturer capturer1;
deadbeef5a4a75a2016-06-02 16:23:38 -0700548 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer1));
pbos1cb121d2015-09-14 11:38:38 -0700549
550 cricket::CapturedFrame frame;
551 frame.width = 1280;
552 frame.height = 720;
553 frame.fourcc = cricket::FOURCC_I420;
nissed73c99c2016-02-12 01:01:11 -0800554 frame.data_size = frame.width * frame.height +
555 2 * ((frame.width + 1) / 2) * ((frame.height + 1) / 2);
kwiberg686a8ef2016-02-26 03:00:35 -0800556 std::unique_ptr<char[]> data(new char[frame.data_size]);
pbos1cb121d2015-09-14 11:38:38 -0700557 frame.data = data.get();
558 memset(frame.data, 1, frame.data_size);
nisseb17712f2016-04-14 02:29:29 -0700559 int64_t initial_timestamp = rtc::TimeNanos();
560 frame.time_stamp = initial_timestamp;
pbos1cb121d2015-09-14 11:38:38 -0700561
562 // Deliver initial frame.
563 capturer1.SignalCapturedFrame(&frame);
564 // Deliver next frame 1 second later.
565 frame.time_stamp += rtc::kNumNanosecsPerSec;
566 rtc::Thread::Current()->SleepMs(1000);
567 capturer1.SignalCapturedFrame(&frame);
568
569 int64_t capturer1_last_timestamp = stream->GetLastTimestamp();
570 // Reset input source, should still be continuous even though input-frame
571 // timestamp is less than before.
572 FakeVideoCapturer capturer2;
deadbeef5a4a75a2016-06-02 16:23:38 -0700573 EXPECT_TRUE(channel->SetVideoSend(kSsrc, true, nullptr, &capturer2));
pbos1cb121d2015-09-14 11:38:38 -0700574
575 rtc::Thread::Current()->SleepMs(1);
576 // Deliver with a timestamp (10 seconds) before the previous initial one,
577 // these should not be related at all anymore and it should still work fine.
nisseb17712f2016-04-14 02:29:29 -0700578 frame.time_stamp = initial_timestamp - 10 * rtc::kNumNanosecsPerSec;
pbos1cb121d2015-09-14 11:38:38 -0700579 capturer2.SignalCapturedFrame(&frame);
580
581 // New timestamp should be at least 1ms in the future and not old.
582 EXPECT_GT(stream->GetLastTimestamp(), capturer1_last_timestamp);
583
584 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
585}
586
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000587VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalEncoderFactory(
588 cricket::WebRtcVideoEncoderFactory* encoder_factory,
589 const std::vector<VideoCodec>& codecs) {
590 engine_.SetExternalEncoderFactory(encoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200591 engine_.Init();
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000592
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000593 VideoMediaChannel* channel =
nisse51542be2016-02-12 02:27:06 -0800594 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200595 cricket::VideoSendParameters parameters;
596 parameters.codecs = codecs;
597 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000598
599 return channel;
600}
601
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000602VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalDecoderFactory(
603 cricket::WebRtcVideoDecoderFactory* decoder_factory,
604 const std::vector<VideoCodec>& codecs) {
605 engine_.SetExternalDecoderFactory(decoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200606 engine_.Init();
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000607
608 VideoMediaChannel* channel =
nisse51542be2016-02-12 02:27:06 -0800609 engine_.CreateChannel(call_.get(), MediaConfig(), VideoOptions());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200610 cricket::VideoRecvParameters parameters;
611 parameters.codecs = codecs;
612 EXPECT_TRUE(channel->SetRecvParameters(parameters));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000613
614 return channel;
615}
616
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000617TEST_F(WebRtcVideoEngine2Test, UsesSimulcastAdapterForVp8Factories) {
618 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
619 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
620 std::vector<cricket::VideoCodec> codecs;
621 codecs.push_back(kVp8Codec);
622
kwiberg686a8ef2016-02-26 03:00:35 -0800623 std::unique_ptr<VideoMediaChannel> channel(
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000624 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
625
Peter Boström0c4e06b2015-10-07 12:23:21 +0200626 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000627
628 EXPECT_TRUE(
629 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
630 EXPECT_TRUE(channel->SetSend(true));
631
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000632 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700633 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, &capturer));
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000634 EXPECT_EQ(cricket::CS_RUNNING,
635 capturer.Start(capturer.GetSupportedFormats()->front()));
636 EXPECT_TRUE(capturer.CaptureFrame());
637
pbos14fe7082016-04-20 06:35:56 -0700638 ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(2));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000639
640 // Verify that encoders are configured for simulcast through adapter
641 // (increasing resolution and only configured to send one stream each).
642 int prev_width = -1;
643 for (size_t i = 0; i < encoder_factory.encoders().size(); ++i) {
pbos14fe7082016-04-20 06:35:56 -0700644 ASSERT_TRUE(encoder_factory.encoders()[i]->WaitForInitEncode());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000645 webrtc::VideoCodec codec_settings =
646 encoder_factory.encoders()[i]->GetCodecSettings();
647 EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
648 EXPECT_GT(codec_settings.width, prev_width);
649 prev_width = codec_settings.width;
650 }
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000651
deadbeef5a4a75a2016-06-02 16:23:38 -0700652 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, nullptr));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000653
654 channel.reset();
655 ASSERT_EQ(0u, encoder_factory.encoders().size());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000656}
657
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000658TEST_F(WebRtcVideoEngine2Test, ChannelWithExternalH264CanChangeToInternalVp8) {
659 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
660 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
661 std::vector<cricket::VideoCodec> codecs;
662 codecs.push_back(kH264Codec);
663
kwiberg686a8ef2016-02-26 03:00:35 -0800664 std::unique_ptr<VideoMediaChannel> channel(
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000665 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
666
667 EXPECT_TRUE(
668 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
669 ASSERT_EQ(1u, encoder_factory.encoders().size());
670
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200671 cricket::VideoSendParameters parameters;
672 parameters.codecs.push_back(kVp8Codec);
673 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000674 ASSERT_EQ(0u, encoder_factory.encoders().size());
675}
676
677TEST_F(WebRtcVideoEngine2Test,
678 DontUseExternalEncoderFactoryForUnsupportedCodecs) {
679 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
680 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
681 std::vector<cricket::VideoCodec> codecs;
682 codecs.push_back(kVp8Codec);
683
kwiberg686a8ef2016-02-26 03:00:35 -0800684 std::unique_ptr<VideoMediaChannel> channel(
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000685 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
686
687 EXPECT_TRUE(
688 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000689 // Make sure DestroyVideoEncoder was called on the factory.
690 ASSERT_EQ(0u, encoder_factory.encoders().size());
691}
692
693TEST_F(WebRtcVideoEngine2Test,
694 UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
695 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
696 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
697 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
698
699 std::vector<cricket::VideoCodec> codecs;
700 codecs.push_back(kVp8Codec);
701
kwiberg686a8ef2016-02-26 03:00:35 -0800702 std::unique_ptr<VideoMediaChannel> channel(
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000703 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
704
Peter Boström0c4e06b2015-10-07 12:23:21 +0200705 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000706
707 EXPECT_TRUE(
708 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
709 EXPECT_TRUE(channel->SetSend(true));
710
711 // Send a fake frame, or else the media engine will configure the simulcast
712 // encoder adapter at a low-enough size that it'll only create a single
713 // encoder layer.
714 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700715 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), true, nullptr, &capturer));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000716 EXPECT_EQ(cricket::CS_RUNNING,
717 capturer.Start(capturer.GetSupportedFormats()->front()));
718 EXPECT_TRUE(capturer.CaptureFrame());
719
pbos14fe7082016-04-20 06:35:56 -0700720 ASSERT_TRUE(encoder_factory.WaitForCreatedVideoEncoders(2));
721 ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000722 EXPECT_EQ(webrtc::kVideoCodecVP8,
723 encoder_factory.encoders()[0]->GetCodecSettings().codecType);
724
725 channel.reset();
726 // Make sure DestroyVideoEncoder was called on the factory.
727 EXPECT_EQ(0u, encoder_factory.encoders().size());
728}
729
730TEST_F(WebRtcVideoEngine2Test,
731 DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
732 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
733 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
734 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
735
736 std::vector<cricket::VideoCodec> codecs;
737 codecs.push_back(kH264Codec);
738
kwiberg686a8ef2016-02-26 03:00:35 -0800739 std::unique_ptr<VideoMediaChannel> channel(
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000740 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
741
742 EXPECT_TRUE(
743 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
744 ASSERT_EQ(1u, encoder_factory.encoders().size());
pbos14fe7082016-04-20 06:35:56 -0700745 ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000746 EXPECT_EQ(webrtc::kVideoCodecH264,
747 encoder_factory.encoders()[0]->GetCodecSettings().codecType);
748
749 channel.reset();
750 // Make sure DestroyVideoEncoder was called on the factory.
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000751 ASSERT_EQ(0u, encoder_factory.encoders().size());
752}
753
noahricfdac5162015-08-27 01:59:29 -0700754TEST_F(WebRtcVideoEngine2Test, SimulcastDisabledForH264) {
755 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
756 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
757 std::vector<cricket::VideoCodec> codecs;
758 codecs.push_back(kH264Codec);
759
kwiberg686a8ef2016-02-26 03:00:35 -0800760 std::unique_ptr<VideoMediaChannel> channel(
noahricfdac5162015-08-27 01:59:29 -0700761 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
762
Peter Boström0c4e06b2015-10-07 12:23:21 +0200763 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
noahricfdac5162015-08-27 01:59:29 -0700764 EXPECT_TRUE(
765 channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs)));
Peter Boströmce23bee2016-02-02 14:14:30 +0100766
767 // Send a frame of 720p. This should trigger a "real" encoder initialization.
noahricfdac5162015-08-27 01:59:29 -0700768 cricket::VideoFormat format(
769 1280, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
Peter Boströmce23bee2016-02-02 14:14:30 +0100770 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -0700771 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], true, nullptr, &capturer));
Peter Boströmce23bee2016-02-02 14:14:30 +0100772 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(format));
773 EXPECT_TRUE(capturer.CaptureFrame());
774
noahricfdac5162015-08-27 01:59:29 -0700775 ASSERT_EQ(1u, encoder_factory.encoders().size());
776 FakeWebRtcVideoEncoder* encoder = encoder_factory.encoders()[0];
pbos14fe7082016-04-20 06:35:56 -0700777 ASSERT_TRUE(encoder_factory.encoders()[0]->WaitForInitEncode());
noahricfdac5162015-08-27 01:59:29 -0700778 EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
779 EXPECT_EQ(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
deadbeef5a4a75a2016-06-02 16:23:38 -0700780 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], true, nullptr, nullptr));
noahricfdac5162015-08-27 01:59:29 -0700781}
782
hbosbab934b2016-01-27 01:36:03 -0800783// Test that external codecs are added to the end of the supported codec list.
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000784TEST_F(WebRtcVideoEngine2Test, ReportSupportedExternalCodecs) {
785 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
hbosbab934b2016-01-27 01:36:03 -0800786 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecUnknown,
787 "FakeExternalCodec");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000788 engine_.SetExternalEncoderFactory(&encoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200789 engine_.Init();
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000790
791 std::vector<cricket::VideoCodec> codecs(engine_.codecs());
792 ASSERT_GE(codecs.size(), 2u);
793 cricket::VideoCodec internal_codec = codecs.front();
794 cricket::VideoCodec external_codec = codecs.back();
795
796 // The external codec will appear at last.
797 EXPECT_EQ("VP8", internal_codec.name);
hbosbab934b2016-01-27 01:36:03 -0800798 EXPECT_EQ("FakeExternalCodec", external_codec.name);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000799}
800
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000801TEST_F(WebRtcVideoEngine2Test, RegisterExternalDecodersIfSupported) {
802 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
803 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200804 cricket::VideoRecvParameters parameters;
805 parameters.codecs.push_back(kVp8Codec);
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000806
kwiberg686a8ef2016-02-26 03:00:35 -0800807 std::unique_ptr<VideoMediaChannel> channel(
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200808 SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000809
810 EXPECT_TRUE(
811 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
812 ASSERT_EQ(1u, decoder_factory.decoders().size());
813
814 // Setting codecs of the same type should not reallocate the decoder.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200815 EXPECT_TRUE(channel->SetRecvParameters(parameters));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000816 EXPECT_EQ(1, decoder_factory.GetNumCreatedDecoders());
817
818 // Remove stream previously added to free the external decoder instance.
819 EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
820 EXPECT_EQ(0u, decoder_factory.decoders().size());
821}
822
823// Verifies that we can set up decoders that are not internally supported.
824TEST_F(WebRtcVideoEngine2Test, RegisterExternalH264DecoderIfSupported) {
825 // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We
826 // can't even query the WebRtcVideoDecoderFactory for supported codecs.
827 // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
828 // codecs.
829 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
830 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
831 engine_.SetExternalEncoderFactory(&encoder_factory);
832 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
833 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264);
834 std::vector<cricket::VideoCodec> codecs;
835 codecs.push_back(kH264Codec);
836
kwiberg686a8ef2016-02-26 03:00:35 -0800837 std::unique_ptr<VideoMediaChannel> channel(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000838 SetUpForExternalDecoderFactory(&decoder_factory, codecs));
839
840 EXPECT_TRUE(
841 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
842 ASSERT_EQ(1u, decoder_factory.decoders().size());
843}
844
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000845class WebRtcVideoChannel2BaseTest
846 : public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> {
847 protected:
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000848 typedef VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> Base;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000849
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000850 cricket::VideoCodec DefaultCodec() override { return kVp8Codec; }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000851};
852
sakal1fd95952016-06-22 00:46:15 -0700853// Verifies that id given in stream params is passed to the decoder factory.
854TEST_F(WebRtcVideoEngine2Test, StreamParamsIdPassedToDecoderFactory) {
855 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
856 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
857 cricket::VideoRecvParameters parameters;
858 parameters.codecs.push_back(kVp8Codec);
859
860 std::unique_ptr<VideoMediaChannel> channel(
861 SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs));
862
863 StreamParams sp = cricket::StreamParams::CreateLegacy(kSsrc);
864 sp.id = "FakeStreamParamsId";
865 EXPECT_TRUE(channel->AddRecvStream(sp));
866 EXPECT_EQ(1u, decoder_factory.decoders().size());
867
868 std::vector<cricket::VideoDecoderParams> params = decoder_factory.params();
869 ASSERT_EQ(1u, params.size());
870 EXPECT_EQ(sp.id, params[0].receive_stream_id);
871}
872
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000873#define WEBRTC_BASE_TEST(test) \
874 TEST_F(WebRtcVideoChannel2BaseTest, test) { Base::test(); }
875
876#define WEBRTC_DISABLED_BASE_TEST(test) \
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000877 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_##test) { Base::test(); }
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000878
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000879WEBRTC_BASE_TEST(SetSend);
880WEBRTC_BASE_TEST(SetSendWithoutCodecs);
881WEBRTC_BASE_TEST(SetSendSetsTransportBufferSizes);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000882
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000883WEBRTC_BASE_TEST(GetStats);
884WEBRTC_BASE_TEST(GetStatsMultipleRecvStreams);
885WEBRTC_BASE_TEST(GetStatsMultipleSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000886
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000887WEBRTC_BASE_TEST(SetSendBandwidth);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000888
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000889WEBRTC_BASE_TEST(SetSendSsrc);
890WEBRTC_BASE_TEST(SetSendSsrcAfterSetCodecs);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000891
nisse08582ff2016-02-04 01:24:52 -0800892WEBRTC_BASE_TEST(SetSink);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000893
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000894WEBRTC_BASE_TEST(AddRemoveSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000895
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000896WEBRTC_BASE_TEST(SimulateConference);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000897
Alejandro Luebs947c02d2016-06-15 15:39:46 -0700898WEBRTC_DISABLED_BASE_TEST(AddRemoveCapturer);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000899
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000900WEBRTC_BASE_TEST(RemoveCapturerWithoutAdd);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000901
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000902WEBRTC_BASE_TEST(AddRemoveCapturerMultipleSources);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000903
904// TODO(pbos): Figure out why this fails so often.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000905WEBRTC_DISABLED_BASE_TEST(HighAspectHighHeightCapturer);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000906
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000907WEBRTC_BASE_TEST(RejectEmptyStreamParams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000908
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000909WEBRTC_BASE_TEST(AdaptResolution16x10);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000910
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000911WEBRTC_BASE_TEST(AdaptResolution4x3);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000912
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000913// TODO(juberti): Restore this test once we support sending 0 fps.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000914WEBRTC_DISABLED_BASE_TEST(AdaptDropAllFrames);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000915// TODO(juberti): Understand why we get decode errors on this test.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000916WEBRTC_DISABLED_BASE_TEST(AdaptFramerate);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000917
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +0000918WEBRTC_BASE_TEST(SendsLowerResolutionOnSmallerFrames);
919
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +0000920WEBRTC_BASE_TEST(MultipleSendStreams);
921
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000922TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Vga) {
deadbeef67cf2c12016-04-13 10:07:16 -0700923 SendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000924}
925
926TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Qvga) {
deadbeef67cf2c12016-04-13 10:07:16 -0700927 SendAndReceive(cricket::VideoCodec(100, "VP8", 320, 200, 30));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000928}
929
930TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8SvcQqvga) {
deadbeef67cf2c12016-04-13 10:07:16 -0700931 SendAndReceive(cricket::VideoCodec(100, "VP8", 160, 100, 30));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000932}
933
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000934TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) {
Peter Boströmd1f584b2016-04-20 16:31:53 +0200935 // Set a high bitrate to not be downscaled by VP8 due to low initial start
936 // bitrates. This currently happens at <250k, and two streams sharing 300k
937 // initially will use QVGA instead of VGA.
938 // TODO(pbos): Set up the quality scaler so that both senders reliably start
939 // at QVGA, then verify that instead.
940 cricket::VideoCodec codec = kVp8Codec;
941 codec.params[kCodecParamStartBitrate] = "1000000";
942 Base::TwoStreamsSendAndReceive(codec);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000943}
944
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200945class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000946 public:
stefanc1aeaf02015-10-15 07:26:07 -0700947 WebRtcVideoChannel2Test() : WebRtcVideoChannel2Test("") {}
948 explicit WebRtcVideoChannel2Test(const char* field_trials)
949 : WebRtcVideoEngine2Test(field_trials), last_ssrc_(0) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000950 void SetUp() override {
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200951 fake_call_.reset(new FakeCall(webrtc::Call::Config()));
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200952 engine_.Init();
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200953 channel_.reset(
nisse51542be2016-02-12 02:27:06 -0800954 engine_.CreateChannel(fake_call_.get(), MediaConfig(), VideoOptions()));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000955 last_ssrc_ = 123;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200956 send_parameters_.codecs = engine_.codecs();
957 recv_parameters_.codecs = engine_.codecs();
958 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000959 }
960
961 protected:
962 FakeVideoSendStream* AddSendStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000963 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000964 }
965
966 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000967 size_t num_streams = fake_call_->GetVideoSendStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000968 EXPECT_TRUE(channel_->AddSendStream(sp));
969 std::vector<FakeVideoSendStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000970 fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000971 EXPECT_EQ(num_streams + 1, streams.size());
972 return streams[streams.size() - 1];
973 }
974
975 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000976 return fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000977 }
978
979 FakeVideoReceiveStream* AddRecvStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000980 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000981 }
982
983 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000984 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000985 EXPECT_TRUE(channel_->AddRecvStream(sp));
986 std::vector<FakeVideoReceiveStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000987 fake_call_->GetVideoReceiveStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000988 EXPECT_EQ(num_streams + 1, streams.size());
989 return streams[streams.size() - 1];
990 }
991
pbos@webrtc.org00873182014-11-25 14:03:34 +0000992 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
993 int expected_min_bitrate_bps,
994 const char* start_bitrate_kbps,
995 int expected_start_bitrate_bps,
996 const char* max_bitrate_kbps,
997 int expected_max_bitrate_bps) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200998 auto& codecs = send_parameters_.codecs;
999 codecs.clear();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001000 codecs.push_back(kVp8Codec);
pbos@webrtc.org00873182014-11-25 14:03:34 +00001001 codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps;
1002 codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps;
1003 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001004 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001005
pbos@webrtc.org00873182014-11-25 14:03:34 +00001006 EXPECT_EQ(expected_min_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +01001007 fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00001008 EXPECT_EQ(expected_start_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +01001009 fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00001010 EXPECT_EQ(expected_max_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +01001011 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001012 }
1013
isheriff6f8d6862016-05-26 11:24:55 -07001014 void TestSetSendRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001015 // Enable extension.
1016 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001017 cricket::VideoSendParameters parameters = send_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07001018 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001019 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001020 FakeVideoSendStream* send_stream =
1021 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1022
1023 // Verify the send extension id.
1024 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1025 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001026 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001027 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001028 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001029 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
1030 // receivers.
1031 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
1032 ->GetConfig()
1033 .rtp.extensions.empty());
1034
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001035 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001036 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001037 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1038 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001039 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
1040
1041 // Verify that adding receive RTP header extensions adds them for existing
1042 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001043 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001044 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001045 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1046 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001047 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001048 }
1049
isheriff6f8d6862016-05-26 11:24:55 -07001050 void TestSetRecvRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001051 // Enable extension.
1052 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001053 cricket::VideoRecvParameters parameters = recv_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07001054 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001055 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001056
1057 FakeVideoReceiveStream* recv_stream =
1058 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1059
1060 // Verify the recv extension id.
1061 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1062 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001063 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001064 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001065 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001066
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001067 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
1068 // senders.
1069 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
1070 ->GetConfig()
1071 .rtp.extensions.empty());
1072
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001073 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001074 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001075 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
1076 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001077 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
1078
1079 // Verify that adding receive RTP header extensions adds them for existing
1080 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001081 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001082 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001083 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1084 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07001085 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001086 }
1087
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001088 void TestExtensionFilter(const std::vector<std::string>& extensions,
1089 const std::string& expected_extension) {
1090 cricket::VideoSendParameters parameters = send_parameters_;
1091 int expected_id = -1;
1092 int id = 1;
1093 for (const std::string& extension : extensions) {
1094 if (extension == expected_extension)
1095 expected_id = id;
isheriff6f8d6862016-05-26 11:24:55 -07001096 parameters.extensions.push_back(RtpExtension(extension, id++));
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001097 }
1098 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1099 FakeVideoSendStream* send_stream =
1100 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1101
1102 // Verify that only one of them has been set, and that it is the one with
1103 // highest priority (transport sequence number).
1104 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1105 EXPECT_EQ(expected_id, send_stream->GetConfig().rtp.extensions[0].id);
1106 EXPECT_EQ(expected_extension,
isheriff6f8d6862016-05-26 11:24:55 -07001107 send_stream->GetConfig().rtp.extensions[0].uri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001108 }
1109
Erik SprĂ¥ngefbde372015-04-29 16:21:28 +02001110 void TestCpuAdaptation(bool enable_overuse, bool is_screenshare);
Peter Boström3548dd22015-05-22 18:48:36 +02001111 void TestReceiverLocalSsrcConfiguration(bool receiver_first);
noahricd10a68e2015-07-10 11:27:55 -07001112 void TestReceiveUnsignalledSsrcPacket(uint8_t payload_type,
1113 bool expect_created_receive_stream);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001114
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001115 FakeVideoSendStream* SetDenoisingOption(
nisse05103312016-03-16 02:22:50 -07001116 uint32_t ssrc,
nisse0db023a2016-03-01 04:29:59 -08001117 cricket::FakeVideoCapturer* capturer,
1118 bool enabled) {
nisse05103312016-03-16 02:22:50 -07001119 cricket::VideoOptions options;
1120 options.video_noise_reduction = rtc::Optional<bool>(enabled);
deadbeef5a4a75a2016-06-02 16:23:38 -07001121 EXPECT_TRUE(channel_->SetVideoSend(ssrc, true, &options, capturer));
nisse0db023a2016-03-01 04:29:59 -08001122 // Options only take effect on the next frame.
1123 EXPECT_TRUE(capturer->CaptureFrame());
1124
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001125 return fake_call_->GetVideoSendStreams().back();
1126 }
1127
Peter Boström2feafdb2015-09-09 14:32:14 +02001128 FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) {
1129 const int kRtxSsrcOffset = 0xDEADBEEF;
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001130 last_ssrc_ += 3;
Peter Boström2feafdb2015-09-09 14:32:14 +02001131 std::vector<uint32_t> ssrcs;
1132 std::vector<uint32_t> rtx_ssrcs;
1133 uint32_t num_streams = enabled ? 3 : 1;
1134 for (uint32_t i = 0; i < num_streams; ++i) {
1135 uint32_t ssrc = last_ssrc_ + i;
1136 ssrcs.push_back(ssrc);
1137 if (with_rtx) {
1138 rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset);
1139 }
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001140 }
Peter Boström2feafdb2015-09-09 14:32:14 +02001141 if (with_rtx) {
1142 return AddSendStream(
1143 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1144 }
1145 return AddSendStream(CreateSimStreamParams("cname", ssrcs));
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001146 }
1147
skvladdc1c62c2016-03-16 19:07:43 -07001148 int GetMaxEncoderBitrate(cricket::FakeVideoCapturer& capturer) {
1149 EXPECT_TRUE(capturer.CaptureFrame());
1150
1151 std::vector<FakeVideoSendStream*> streams =
1152 fake_call_->GetVideoSendStreams();
1153 EXPECT_TRUE(streams.size() > 0);
1154 FakeVideoSendStream* stream = streams[streams.size() - 1];
1155
perkj26091b12016-09-01 01:17:40 -07001156 webrtc::VideoEncoderConfig encoder_config =
1157 stream->GetEncoderConfig().Copy();
skvladdc1c62c2016-03-16 19:07:43 -07001158 EXPECT_EQ(1, encoder_config.streams.size());
1159 return encoder_config.streams[0].max_bitrate_bps;
1160 }
1161
1162 void SetAndExpectMaxBitrate(cricket::FakeVideoCapturer& capturer,
1163 int global_max,
1164 int stream_max,
1165 int expected_encoder_bitrate) {
1166 VideoSendParameters limited_send_params = send_parameters_;
1167 limited_send_params.max_bandwidth_bps = global_max;
1168 EXPECT_TRUE(channel_->SetSendParameters(limited_send_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001169 webrtc::RtpParameters parameters =
1170 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07001171 EXPECT_EQ(1UL, parameters.encodings.size());
1172 parameters.encodings[0].max_bitrate_bps = stream_max;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001173 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07001174 // Read back the parameteres and verify they have the correct value
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07001175 parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07001176 EXPECT_EQ(1UL, parameters.encodings.size());
1177 EXPECT_EQ(stream_max, parameters.encodings[0].max_bitrate_bps);
1178 // Verify that the new value propagated down to the encoder
1179 EXPECT_EQ(expected_encoder_bitrate, GetMaxEncoderBitrate(capturer));
1180 }
1181
kwiberg686a8ef2016-02-26 03:00:35 -08001182 std::unique_ptr<FakeCall> fake_call_;
1183 std::unique_ptr<VideoMediaChannel> channel_;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001184 cricket::VideoSendParameters send_parameters_;
1185 cricket::VideoRecvParameters recv_parameters_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02001186 uint32_t last_ssrc_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001187};
1188
pbos8fc7fa72015-07-15 08:02:58 -07001189TEST_F(WebRtcVideoChannel2Test, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02001190 const uint32_t kVideoSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07001191 const std::string kSyncLabel = "AvSyncLabel";
1192
1193 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc);
1194 sp.sync_label = kSyncLabel;
1195 EXPECT_TRUE(channel_->AddRecvStream(sp));
1196
1197 EXPECT_EQ(1, fake_call_->GetVideoReceiveStreams().size());
1198 EXPECT_EQ(kSyncLabel,
1199 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group)
1200 << "SyncGroup should be set based on sync_label";
1201}
1202
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001203TEST_F(WebRtcVideoChannel2Test, RecvStreamWithSimAndRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001204 cricket::VideoSendParameters parameters;
1205 parameters.codecs = engine_.codecs();
1206 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001207 EXPECT_TRUE(channel_->SetSend(true));
nisse4b4dc862016-02-17 05:25:36 -08001208 parameters.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001209 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001210
1211 // Send side.
Peter Boström0c4e06b2015-10-07 12:23:21 +02001212 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
1213 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001214 FakeVideoSendStream* send_stream = AddSendStream(
1215 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1216
1217 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
1218 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
1219 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
1220
1221 // Receiver side.
1222 FakeVideoReceiveStream* recv_stream = AddRecvStream(
1223 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
Peter Boströmd8b01092016-05-12 16:44:36 +02001224 EXPECT_FALSE(recv_stream->GetConfig().rtp.rtx.empty());
1225 EXPECT_EQ(recv_stream->GetConfig().decoders.size(),
1226 recv_stream->GetConfig().rtp.rtx.size())
1227 << "RTX should be mapped for all decoders/payload types.";
1228 for (const auto& kv : recv_stream->GetConfig().rtp.rtx) {
1229 EXPECT_EQ(rtx_ssrcs[0], kv.second.ssrc);
1230 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001231}
1232
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001233TEST_F(WebRtcVideoChannel2Test, RecvStreamWithRtx) {
1234 // Setup one channel with an associated RTX stream.
1235 cricket::StreamParams params =
1236 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
1237 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
1238 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001239 EXPECT_EQ(kRtxSsrcs1[0],
1240 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001241}
1242
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001243TEST_F(WebRtcVideoChannel2Test, RecvStreamNoRtx) {
1244 // Setup one channel without an associated RTX stream.
1245 cricket::StreamParams params =
1246 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
1247 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
1248 ASSERT_TRUE(recv_stream->GetConfig().rtp.rtx.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001249}
1250
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001251TEST_F(WebRtcVideoChannel2Test, NoHeaderExtesionsByDefault) {
1252 FakeVideoSendStream* send_stream =
1253 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
1254 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
1255
1256 FakeVideoReceiveStream* recv_stream =
1257 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
1258 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001259}
1260
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001261// Test support for RTP timestamp offset header extension.
1262TEST_F(WebRtcVideoChannel2Test, SendRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001263 TestSetSendRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001264}
isheriff6f8d6862016-05-26 11:24:55 -07001265
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001266TEST_F(WebRtcVideoChannel2Test, RecvRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001267 TestSetRecvRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001268}
1269
1270// Test support for absolute send time header extension.
1271TEST_F(WebRtcVideoChannel2Test, SendAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001272 TestSetSendRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001273}
isheriff6f8d6862016-05-26 11:24:55 -07001274
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001275TEST_F(WebRtcVideoChannel2Test, RecvAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001276 TestSetRecvRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001277}
1278
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001279TEST_F(WebRtcVideoChannel2Test, FiltersExtensionsPicksTransportSeqNum) {
1280 // Enable three redundant extensions.
1281 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07001282 extensions.push_back(RtpExtension::kAbsSendTimeUri);
1283 extensions.push_back(RtpExtension::kTimestampOffsetUri);
1284 extensions.push_back(RtpExtension::kTransportSequenceNumberUri);
1285 TestExtensionFilter(extensions, RtpExtension::kTransportSequenceNumberUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001286}
1287
1288TEST_F(WebRtcVideoChannel2Test, FiltersExtensionsPicksAbsSendTime) {
1289 // Enable two redundant extensions.
1290 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07001291 extensions.push_back(RtpExtension::kAbsSendTimeUri);
1292 extensions.push_back(RtpExtension::kTimestampOffsetUri);
1293 TestExtensionFilter(extensions, RtpExtension::kAbsSendTimeUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001294}
1295
stefanc1aeaf02015-10-15 07:26:07 -07001296class WebRtcVideoChannel2WithSendSideBweTest : public WebRtcVideoChannel2Test {
1297 public:
1298 WebRtcVideoChannel2WithSendSideBweTest()
1299 : WebRtcVideoChannel2Test("WebRTC-SendSideBwe/Enabled/") {}
1300};
1301
1302// Test support for transport sequence number header extension.
1303TEST_F(WebRtcVideoChannel2WithSendSideBweTest,
1304 SendTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001305 TestSetSendRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07001306}
1307TEST_F(WebRtcVideoChannel2WithSendSideBweTest,
1308 RecvTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001309 TestSetRecvRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07001310}
1311
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001312// Test support for video rotation header extension.
1313TEST_F(WebRtcVideoChannel2Test, SendVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001314 TestSetSendRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001315}
1316TEST_F(WebRtcVideoChannel2Test, RecvVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07001317 TestSetRecvRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001318}
1319
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001320TEST_F(WebRtcVideoChannel2Test, IdenticalSendExtensionsDoesntRecreateStream) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001321 const int kAbsSendTimeId = 1;
1322 const int kVideoRotationId = 2;
isheriff6f8d6862016-05-26 11:24:55 -07001323 send_parameters_.extensions.push_back(
1324 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
1325 send_parameters_.extensions.push_back(
1326 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001327
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001328 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001329 FakeVideoSendStream* send_stream =
1330 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1331
1332 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Stefan Holmerbbaf3632015-10-29 18:53:23 +01001333 ASSERT_EQ(2u, send_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001334
1335 // Setting the same extensions (even if in different order) shouldn't
1336 // reallocate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001337 std::reverse(send_parameters_.extensions.begin(),
1338 send_parameters_.extensions.end());
1339 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001340
1341 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1342
1343 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001344 send_parameters_.extensions.resize(1);
1345 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001346
1347 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
1348}
1349
1350TEST_F(WebRtcVideoChannel2Test, IdenticalRecvExtensionsDoesntRecreateStream) {
1351 const int kTOffsetId = 1;
1352 const int kAbsSendTimeId = 2;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001353 const int kVideoRotationId = 3;
isheriff6f8d6862016-05-26 11:24:55 -07001354 recv_parameters_.extensions.push_back(
1355 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
1356 recv_parameters_.extensions.push_back(
1357 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
1358 recv_parameters_.extensions.push_back(
1359 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001360
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001361 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Peter Boström54be3e02015-05-25 15:04:24 +02001362 FakeVideoReceiveStream* recv_stream =
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001363 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1364
1365 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Peter Boström54be3e02015-05-25 15:04:24 +02001366 ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001367
1368 // Setting the same extensions (even if in different order) shouldn't
1369 // reallocate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001370 std::reverse(recv_parameters_.extensions.begin(),
1371 recv_parameters_.extensions.end());
1372 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001373
1374 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
1375
1376 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001377 recv_parameters_.extensions.resize(1);
1378 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001379
1380 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
1381}
1382
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001383TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001384 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001385 const int kUnsupportedId = 1;
1386 const int kTOffsetId = 2;
1387
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001388 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001389 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001390 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001391 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001392 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001393 FakeVideoSendStream* send_stream =
1394 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1395
1396 // Only timestamp offset extension is set to send stream,
1397 // unsupported rtp extension is ignored.
1398 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07001399 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
1400 send_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001401}
1402
1403TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001404 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001405 const int kUnsupportedId = 1;
1406 const int kTOffsetId = 2;
1407
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001408 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001409 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001410 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001411 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001412 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001413 FakeVideoReceiveStream* recv_stream =
1414 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1415
1416 // Only timestamp offset extension is set to receive stream,
1417 // unsupported rtp extension is ignored.
1418 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07001419 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
1420 recv_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001421}
1422
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001423TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02001424 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00001425 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07001426 send_parameters_.extensions.push_back(
1427 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001428 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001429 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1430 }
1431}
1432
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001433TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02001434 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00001435 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07001436 recv_parameters_.extensions.push_back(
1437 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001438 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001439 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1440 }
1441}
1442
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001443TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001444 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001445 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001446 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001447 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001448 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001449 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001450
1451 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001452 send_parameters_.extensions.clear();
1453 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001454 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001455 send_parameters_.extensions.push_back(send_parameters_.extensions.back());
1456 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001457}
1458
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001459TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001460 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001461 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001462 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001463 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001464 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001465 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001466
1467 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001468 recv_parameters_.extensions.clear();
1469 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001470 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001471 recv_parameters_.extensions.push_back(recv_parameters_.extensions.back());
1472 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001473}
1474
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001475TEST_F(WebRtcVideoChannel2Test, AddRecvStreamOnlyUsesOneReceiveStream) {
1476 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001477 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001478}
1479
Peter Boströmd7da1202015-06-05 14:09:38 +02001480TEST_F(WebRtcVideoChannel2Test, RtcpIsCompoundByDefault) {
1481 FakeVideoReceiveStream* stream = AddRecvStream();
pbosda903ea2015-10-02 02:36:56 -07001482 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream->GetConfig().rtp.rtcp_mode);
Peter Boströmd7da1202015-06-05 14:09:38 +02001483}
1484
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001485TEST_F(WebRtcVideoChannel2Test, RembIsEnabledByDefault) {
1486 FakeVideoReceiveStream* stream = AddRecvStream();
1487 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001488}
1489
stefan43edf0f2015-11-20 18:05:48 -08001490TEST_F(WebRtcVideoChannel2Test, TransportCcIsEnabledByDefault) {
1491 FakeVideoReceiveStream* stream = AddRecvStream();
1492 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1493}
1494
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001495TEST_F(WebRtcVideoChannel2Test, RembCanBeEnabledAndDisabled) {
1496 FakeVideoReceiveStream* stream = AddRecvStream();
1497 EXPECT_TRUE(stream->GetConfig().rtp.remb);
1498
Peter Boström126c03e2015-05-11 12:48:12 +02001499 // Verify that REMB is turned off when send(!) codecs without REMB are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001500 cricket::VideoSendParameters parameters;
1501 parameters.codecs.push_back(kVp8Codec);
1502 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1503 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001504 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001505 EXPECT_FALSE(stream->GetConfig().rtp.remb);
1506
1507 // Verify that REMB is turned on when setting default codecs since the
1508 // default codecs have REMB enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001509 parameters.codecs = engine_.codecs();
1510 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001511 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001512 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001513}
1514
stefan43edf0f2015-11-20 18:05:48 -08001515TEST_F(WebRtcVideoChannel2Test, TransportCcCanBeEnabledAndDisabled) {
1516 FakeVideoReceiveStream* stream = AddRecvStream();
1517 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1518
1519 // Verify that transport cc feedback is turned off when send(!) codecs without
1520 // transport cc feedback are set.
1521 cricket::VideoSendParameters parameters;
1522 parameters.codecs.push_back(kVp8Codec);
1523 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1524 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1525 stream = fake_call_->GetVideoReceiveStreams()[0];
1526 EXPECT_FALSE(stream->GetConfig().rtp.transport_cc);
1527
1528 // Verify that transport cc feedback is turned on when setting default codecs
1529 // since the default codecs have transport cc feedback enabled.
1530 parameters.codecs = engine_.codecs();
1531 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1532 stream = fake_call_->GetVideoReceiveStreams()[0];
1533 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1534}
1535
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001536TEST_F(WebRtcVideoChannel2Test, NackIsEnabledByDefault) {
1537 VerifyCodecHasDefaultFeedbackParams(default_codec_);
1538
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001539 cricket::VideoSendParameters parameters;
1540 parameters.codecs = engine_.codecs();
1541 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org19864742014-05-30 07:35:47 +00001542 EXPECT_TRUE(channel_->SetSend(true));
1543
1544 // Send side.
1545 FakeVideoSendStream* send_stream =
1546 AddSendStream(cricket::StreamParams::CreateLegacy(1));
1547 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1548
1549 // Receiver side.
1550 FakeVideoReceiveStream* recv_stream =
1551 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
1552 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1553
1554 // Nack history size should match between sender and receiver.
1555 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
1556 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001557}
1558
Peter Boström67c9df72015-05-11 14:34:58 +02001559TEST_F(WebRtcVideoChannel2Test, NackCanBeEnabledAndDisabled) {
Peter Boström67c9df72015-05-11 14:34:58 +02001560 FakeVideoSendStream* send_stream = AddSendStream();
Peter Boström3548dd22015-05-22 18:48:36 +02001561 FakeVideoReceiveStream* recv_stream = AddRecvStream();
Peter Boström67c9df72015-05-11 14:34:58 +02001562
1563 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1564 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1565
1566 // Verify that NACK is turned off when send(!) codecs without NACK are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001567 cricket::VideoSendParameters parameters;
1568 parameters.codecs.push_back(kVp8Codec);
1569 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1570 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02001571 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1572 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
1573 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001574 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
1575
Peter Boström67c9df72015-05-11 14:34:58 +02001576 // Verify that NACK is turned on when setting default codecs since the
1577 // default codecs have NACK enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001578 parameters.codecs = engine_.codecs();
1579 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02001580 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1581 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1582 send_stream = fake_call_->GetVideoSendStreams()[0];
1583 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001584}
1585
Peter Boströme7ba0862016-03-12 00:02:28 +01001586// This test verifies that new frame sizes reconfigures encoders even though not
1587// (yet) sending. The purpose of this is to permit encoding as quickly as
1588// possible once we start sending. Likely the frames being input are from the
1589// same source that will be sent later, which just means that we're ready
1590// earlier.
1591TEST_F(WebRtcVideoChannel2Test, ReconfiguresEncodersWhenNotSending) {
1592 cricket::VideoSendParameters parameters;
1593 parameters.codecs.push_back(kVp8Codec720p);
1594 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1595 channel_->SetSend(false);
1596
1597 FakeVideoSendStream* stream = AddSendStream();
1598
1599 // No frames entered, using default dimensions.
1600 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
1601 EXPECT_EQ(176u, streams[0].width);
1602 EXPECT_EQ(144u, streams[0].height);
1603
1604 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07001605 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Peter Boströme7ba0862016-03-12 00:02:28 +01001606 EXPECT_EQ(cricket::CS_RUNNING,
1607 capturer.Start(capturer.GetSupportedFormats()->front()));
1608 EXPECT_TRUE(capturer.CaptureFrame());
1609
1610 // Frame entered, should be reconfigured to new dimensions.
1611 streams = stream->GetVideoStreams();
1612 EXPECT_EQ(kVp8Codec720p.width, streams[0].width);
1613 EXPECT_EQ(kVp8Codec720p.height, streams[0].height);
1614 // No frames should have been actually put in there though.
1615 EXPECT_EQ(0, stream->GetNumberOfSwappedFrames());
1616
deadbeef5a4a75a2016-06-02 16:23:38 -07001617 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boströme7ba0862016-03-12 00:02:28 +01001618}
1619
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001620TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) {
1621 static const int kScreenshareMinBitrateKbps = 800;
1622 cricket::VideoCodec codec = kVp8Codec360p;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001623 cricket::VideoSendParameters parameters;
1624 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001625 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001626 AddSendStream();
1627
deadbeef5a4a75a2016-06-02 16:23:38 -07001628 cricket::FakeVideoCapturer capturer;
nisse05103312016-03-16 02:22:50 -07001629 VideoOptions min_bitrate_options;
1630 min_bitrate_options.screencast_min_bitrate_kbps =
1631 rtc::Optional<int>(kScreenshareMinBitrateKbps);
deadbeef5a4a75a2016-06-02 16:23:38 -07001632 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &min_bitrate_options,
1633 &capturer));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001634 cricket::VideoFormat capture_format_hd =
1635 capturer.GetSupportedFormats()->front();
1636 EXPECT_EQ(1280, capture_format_hd.width);
1637 EXPECT_EQ(720, capture_format_hd.height);
1638 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1639
1640 EXPECT_TRUE(channel_->SetSend(true));
1641
1642 EXPECT_TRUE(capturer.CaptureFrame());
1643 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1644 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1645
1646 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1647
1648 // Verify non-screencast settings.
perkj26091b12016-09-01 01:17:40 -07001649 webrtc::VideoEncoderConfig encoder_config =
1650 send_stream->GetEncoderConfig().Copy();
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001651 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001652 encoder_config.content_type);
1653 EXPECT_EQ(codec.width, encoder_config.streams.front().width);
1654 EXPECT_EQ(codec.height, encoder_config.streams.front().height);
1655 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
1656 << "Non-screenshare shouldn't use min-transmit bitrate.";
1657
deadbeef5a4a75a2016-06-02 16:23:38 -07001658 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkj2d5f0912016-02-29 00:04:41 -08001659 // Removing a capturer triggers a black frame to be sent.
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001660 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
nisse05103312016-03-16 02:22:50 -07001661 VideoOptions screencast_options;
1662 screencast_options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001663 EXPECT_TRUE(
1664 channel_->SetVideoSend(last_ssrc_, true, &screencast_options, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08001665 EXPECT_TRUE(capturer.CaptureFrame());
Niels Möller60653ba2016-03-02 11:41:36 +01001666 // Send stream not recreated after option change.
1667 ASSERT_EQ(send_stream, fake_call_->GetVideoSendStreams().front());
perkj2d5f0912016-02-29 00:04:41 -08001668 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001669
1670 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07001671 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001672 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001673 encoder_config.content_type);
1674 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
1675 encoder_config.min_transmit_bitrate_bps);
1676
1677 EXPECT_EQ(capture_format_hd.width, encoder_config.streams.front().width);
1678 EXPECT_EQ(capture_format_hd.height, encoder_config.streams.front().height);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001679 EXPECT_TRUE(encoder_config.streams[0].temporal_layer_thresholds_bps.empty());
1680
deadbeef5a4a75a2016-06-02 16:23:38 -07001681 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001682}
1683
Niels Möller60653ba2016-03-02 11:41:36 +01001684TEST_F(WebRtcVideoChannel2Test, NoRecreateStreamForScreencast) {
1685 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
1686 ASSERT_TRUE(
1687 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1688 EXPECT_TRUE(channel_->SetSend(true));
1689
1690 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07001691 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001692 EXPECT_EQ(cricket::CS_RUNNING,
1693 capturer.Start(capturer.GetSupportedFormats()->front()));
1694 EXPECT_TRUE(capturer.CaptureFrame());
1695
1696 ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1697 FakeVideoSendStream* stream = fake_call_->GetVideoSendStreams().front();
perkj26091b12016-09-01 01:17:40 -07001698 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
Niels Möller60653ba2016-03-02 11:41:36 +01001699 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
1700 encoder_config.content_type);
1701
1702 EXPECT_EQ(1, stream->GetNumberOfSwappedFrames());
1703
1704 /* Switch to screencast source. We expect a reconfigure of the
1705 * encoder, but no change of the send stream. */
1706 struct VideoOptions video_options;
1707 video_options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001708 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, &video_options, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001709
1710 EXPECT_TRUE(capturer.CaptureFrame());
1711 ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1712 ASSERT_EQ(stream, fake_call_->GetVideoSendStreams().front());
1713 EXPECT_EQ(2, stream->GetNumberOfSwappedFrames());
1714
perkj26091b12016-09-01 01:17:40 -07001715 encoder_config = stream->GetEncoderConfig().Copy();
Niels Möller60653ba2016-03-02 11:41:36 +01001716 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
1717 encoder_config.content_type);
1718
1719 /* Switch back. */
1720 video_options.is_screencast = rtc::Optional<bool>(false);
deadbeef5a4a75a2016-06-02 16:23:38 -07001721 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, &video_options, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001722
1723 EXPECT_TRUE(capturer.CaptureFrame());
1724 ASSERT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1725 ASSERT_EQ(stream, fake_call_->GetVideoSendStreams().front());
1726 EXPECT_EQ(3, stream->GetNumberOfSwappedFrames());
1727
perkj26091b12016-09-01 01:17:40 -07001728 encoder_config = stream->GetEncoderConfig().Copy();
Niels Möller60653ba2016-03-02 11:41:36 +01001729 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
1730 encoder_config.content_type);
1731
deadbeef5a4a75a2016-06-02 16:23:38 -07001732 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr, nullptr));
Niels Möller60653ba2016-03-02 11:41:36 +01001733}
1734
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001735TEST_F(WebRtcVideoChannel2Test,
1736 ConferenceModeScreencastConfiguresTemporalLayer) {
Erik SprĂ¥ng2c4c9142015-06-24 11:24:44 +02001737 static const int kConferenceScreencastTemporalBitrateBps =
1738 ScreenshareLayerConfig::GetDefault().tl0_bitrate_kbps * 1000;
nisse4b4dc862016-02-17 05:25:36 -08001739 send_parameters_.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001740 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001741
1742 AddSendStream();
nisse05103312016-03-16 02:22:50 -07001743 VideoOptions options;
1744 options.is_screencast = rtc::Optional<bool>(true);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001745 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07001746 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001747 cricket::VideoFormat capture_format_hd =
1748 capturer.GetSupportedFormats()->front();
1749 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1750
1751 EXPECT_TRUE(channel_->SetSend(true));
1752
1753 EXPECT_TRUE(capturer.CaptureFrame());
1754 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1755 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1756
perkj26091b12016-09-01 01:17:40 -07001757 webrtc::VideoEncoderConfig encoder_config =
1758 send_stream->GetEncoderConfig().Copy();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001759
1760 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07001761 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001762 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001763 encoder_config.content_type);
1764 ASSERT_EQ(1u, encoder_config.streams.size());
1765 ASSERT_EQ(1u, encoder_config.streams[0].temporal_layer_thresholds_bps.size());
1766 EXPECT_EQ(kConferenceScreencastTemporalBitrateBps,
1767 encoder_config.streams[0].temporal_layer_thresholds_bps[0]);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001768
deadbeef5a4a75a2016-06-02 16:23:38 -07001769 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001770}
1771
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001772TEST_F(WebRtcVideoChannel2Test, SuspendBelowMinBitrateDisabledByDefault) {
1773 FakeVideoSendStream* stream = AddSendStream();
1774 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1775}
1776
nisse0db023a2016-03-01 04:29:59 -08001777TEST_F(WebRtcVideoChannel2Test, SetMediaConfigSuspendBelowMinBitrate) {
1778 MediaConfig media_config = MediaConfig();
1779 media_config.video.suspend_below_min_bitrate = true;
1780
1781 channel_.reset(
1782 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
1783
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001784 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001785
1786 FakeVideoSendStream* stream = AddSendStream();
1787 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
1788
nisse0db023a2016-03-01 04:29:59 -08001789 media_config.video.suspend_below_min_bitrate = false;
1790 channel_.reset(
1791 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
1792
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001793 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001794
nisse0db023a2016-03-01 04:29:59 -08001795 stream = AddSendStream();
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001796 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1797}
1798
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001799TEST_F(WebRtcVideoChannel2Test, Vp8DenoisingEnabledByDefault) {
1800 FakeVideoSendStream* stream = AddSendStream();
1801 webrtc::VideoCodecVP8 vp8_settings;
1802 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1803 EXPECT_TRUE(vp8_settings.denoisingOn);
1804}
1805
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001806TEST_F(WebRtcVideoChannel2Test, VerifyVp8SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001807 cricket::VideoSendParameters parameters;
1808 parameters.codecs.push_back(kVp8Codec720p);
1809 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001810
Peter Boström2feafdb2015-09-09 14:32:14 +02001811 // Single-stream settings should apply with RTX as well (verifies that we
1812 // check number of regular SSRCs and not StreamParams::ssrcs which contains
1813 // both RTX and regular SSRCs).
1814 FakeVideoSendStream* stream = SetUpSimulcast(false, true);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001815
1816 cricket::FakeVideoCapturer capturer;
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001817 EXPECT_EQ(cricket::CS_RUNNING,
1818 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07001819 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001820 channel_->SetSend(true);
1821
1822 EXPECT_TRUE(capturer.CaptureFrame());
1823
pbos4cba4eb2015-10-26 11:18:18 -07001824 webrtc::VideoCodecVP8 vp8_settings;
1825 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1826 EXPECT_TRUE(vp8_settings.denoisingOn)
1827 << "VP8 denoising should be on by default.";
1828
nisse05103312016-03-16 02:22:50 -07001829 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001830
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001831 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1832 EXPECT_FALSE(vp8_settings.denoisingOn);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001833 EXPECT_TRUE(vp8_settings.automaticResizeOn);
1834 EXPECT_TRUE(vp8_settings.frameDroppingOn);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001835
nisse05103312016-03-16 02:22:50 -07001836 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001837
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001838 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1839 EXPECT_TRUE(vp8_settings.denoisingOn);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001840 EXPECT_TRUE(vp8_settings.automaticResizeOn);
1841 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1842
deadbeef5a4a75a2016-06-02 16:23:38 -07001843 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boström2feafdb2015-09-09 14:32:14 +02001844 stream = SetUpSimulcast(true, false);
deadbeef5a4a75a2016-06-02 16:23:38 -07001845 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001846 channel_->SetSend(true);
1847 EXPECT_TRUE(capturer.CaptureFrame());
1848
1849 EXPECT_EQ(3, stream->GetVideoStreams().size());
1850 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1851 // Autmatic resize off when using simulcast.
1852 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1853 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1854
1855 // In screen-share mode, denoising is forced off and simulcast disabled.
nisse05103312016-03-16 02:22:50 -07001856 VideoOptions options;
1857 options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001858 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
Niels Möller60653ba2016-03-02 11:41:36 +01001859
nisse05103312016-03-16 02:22:50 -07001860 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001861
1862 EXPECT_EQ(1, stream->GetVideoStreams().size());
1863 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1864 EXPECT_FALSE(vp8_settings.denoisingOn);
1865 // Resizing and frame dropping always off for screen sharing.
1866 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1867 EXPECT_FALSE(vp8_settings.frameDroppingOn);
1868
nisse05103312016-03-16 02:22:50 -07001869 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001870
1871 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1872 EXPECT_FALSE(vp8_settings.denoisingOn);
1873 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1874 EXPECT_FALSE(vp8_settings.frameDroppingOn);
1875
deadbeef5a4a75a2016-06-02 16:23:38 -07001876 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001877}
1878
deadbeef119760a2016-04-04 11:43:27 -07001879// Test that setting the same options doesn't result in the encoder being
1880// reconfigured.
1881TEST_F(WebRtcVideoChannel2Test, SetIdenticalOptionsDoesntReconfigureEncoder) {
1882 VideoOptions options;
1883 cricket::FakeVideoCapturer capturer;
1884
1885 FakeVideoSendStream* send_stream = AddSendStream();
deadbeef119760a2016-04-04 11:43:27 -07001886 EXPECT_EQ(cricket::CS_RUNNING,
1887 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07001888 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
deadbeef119760a2016-04-04 11:43:27 -07001889 EXPECT_TRUE(capturer.CaptureFrame());
1890 // Expect 2 reconfigurations at this point, from the initial configuration
1891 // and from the dimensions of the first frame.
1892 EXPECT_EQ(2, send_stream->num_encoder_reconfigurations());
1893
1894 // Set the options one more time and expect no additional reconfigurations.
deadbeef5a4a75a2016-06-02 16:23:38 -07001895 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
deadbeef119760a2016-04-04 11:43:27 -07001896 EXPECT_TRUE(capturer.CaptureFrame());
1897 EXPECT_EQ(2, send_stream->num_encoder_reconfigurations());
1898
deadbeef5a4a75a2016-06-02 16:23:38 -07001899 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
deadbeef119760a2016-04-04 11:43:27 -07001900}
1901
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001902class Vp9SettingsTest : public WebRtcVideoChannel2Test {
1903 public:
asaperssonc5dabdd2016-03-21 04:15:50 -07001904 Vp9SettingsTest() : Vp9SettingsTest("") {}
1905 explicit Vp9SettingsTest(const char* field_trials)
1906 : WebRtcVideoChannel2Test(field_trials) {
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001907 encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP9, "VP9");
1908 }
1909 virtual ~Vp9SettingsTest() {}
1910
1911 protected:
1912 void SetUp() override {
1913 engine_.SetExternalEncoderFactory(&encoder_factory_);
1914
1915 WebRtcVideoChannel2Test::SetUp();
1916 }
1917
1918 void TearDown() override {
1919 // Remove references to encoder_factory_ since this will be destroyed
1920 // before channel_ and engine_.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001921 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001922 }
1923
1924 cricket::FakeWebRtcVideoEncoderFactory encoder_factory_;
1925};
1926
1927TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001928 cricket::VideoSendParameters parameters;
1929 parameters.codecs.push_back(kVp9Codec);
1930 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001931
Peter Boström2feafdb2015-09-09 14:32:14 +02001932 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001933
1934 cricket::FakeVideoCapturer capturer;
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001935 EXPECT_EQ(cricket::CS_RUNNING,
1936 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07001937 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001938 channel_->SetSend(true);
1939
1940 EXPECT_TRUE(capturer.CaptureFrame());
1941
pbos4cba4eb2015-10-26 11:18:18 -07001942 webrtc::VideoCodecVP9 vp9_settings;
1943 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1944 EXPECT_FALSE(vp9_settings.denoisingOn)
1945 << "VP9 denoising should be off by default.";
1946
nisse05103312016-03-16 02:22:50 -07001947 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001948
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001949 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1950 EXPECT_FALSE(vp9_settings.denoisingOn);
1951 // Frame dropping always on for real time video.
1952 EXPECT_TRUE(vp9_settings.frameDroppingOn);
1953
nisse05103312016-03-16 02:22:50 -07001954 stream = SetDenoisingOption(last_ssrc_, &capturer, true);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001955
1956 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1957 EXPECT_TRUE(vp9_settings.denoisingOn);
1958 EXPECT_TRUE(vp9_settings.frameDroppingOn);
1959
1960 // In screen-share mode, denoising is forced off.
nisse05103312016-03-16 02:22:50 -07001961 VideoOptions options;
1962 options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07001963 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08001964
nisse05103312016-03-16 02:22:50 -07001965 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001966
1967 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1968 EXPECT_FALSE(vp9_settings.denoisingOn);
1969 // Frame dropping always off for screen sharing.
1970 EXPECT_FALSE(vp9_settings.frameDroppingOn);
1971
nisse05103312016-03-16 02:22:50 -07001972 stream = SetDenoisingOption(last_ssrc_, &capturer, false);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001973
1974 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1975 EXPECT_FALSE(vp9_settings.denoisingOn);
1976 EXPECT_FALSE(vp9_settings.frameDroppingOn);
1977
deadbeef5a4a75a2016-06-02 16:23:38 -07001978 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001979}
1980
asaperssonc5dabdd2016-03-21 04:15:50 -07001981class Vp9SettingsTestWithFieldTrial : public Vp9SettingsTest {
1982 public:
1983 Vp9SettingsTestWithFieldTrial(const char* field_trials)
1984 : Vp9SettingsTest(field_trials) {}
1985
1986 protected:
1987 void VerifySettings(int num_spatial_layers, int num_temporal_layers) {
1988 cricket::VideoSendParameters parameters;
1989 parameters.codecs.push_back(kVp9Codec);
1990 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1991
1992 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
1993
1994 cricket::FakeVideoCapturer capturer;
1995 EXPECT_EQ(cricket::CS_RUNNING,
1996 capturer.Start(capturer.GetSupportedFormats()->front()));
deadbeef5a4a75a2016-06-02 16:23:38 -07001997 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
asaperssonc5dabdd2016-03-21 04:15:50 -07001998 channel_->SetSend(true);
1999
2000 EXPECT_TRUE(capturer.CaptureFrame());
2001
2002 webrtc::VideoCodecVP9 vp9_settings;
2003 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
2004 EXPECT_EQ(num_spatial_layers, vp9_settings.numberOfSpatialLayers);
2005 EXPECT_EQ(num_temporal_layers, vp9_settings.numberOfTemporalLayers);
2006
deadbeef5a4a75a2016-06-02 16:23:38 -07002007 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
asaperssonc5dabdd2016-03-21 04:15:50 -07002008 }
2009};
2010
2011class Vp9SettingsTestWithNoFlag : public Vp9SettingsTestWithFieldTrial {
2012 public:
2013 Vp9SettingsTestWithNoFlag() : Vp9SettingsTestWithFieldTrial("") {}
2014};
2015
2016TEST_F(Vp9SettingsTestWithNoFlag, VerifySettings) {
2017 const int kNumSpatialLayers = 1;
2018 const int kNumTemporalLayers = 1;
2019 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
2020}
2021
2022class Vp9SettingsTestWithInvalidFlag : public Vp9SettingsTestWithFieldTrial {
2023 public:
2024 Vp9SettingsTestWithInvalidFlag()
2025 : Vp9SettingsTestWithFieldTrial("WebRTC-SupportVP9SVC/Default/") {}
2026};
2027
2028TEST_F(Vp9SettingsTestWithInvalidFlag, VerifySettings) {
2029 const int kNumSpatialLayers = 1;
2030 const int kNumTemporalLayers = 1;
2031 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
2032}
2033
2034class Vp9SettingsTestWith2SL3TLFlag : public Vp9SettingsTestWithFieldTrial {
2035 public:
2036 Vp9SettingsTestWith2SL3TLFlag()
2037 : Vp9SettingsTestWithFieldTrial(
2038 "WebRTC-SupportVP9SVC/EnabledByFlag_2SL3TL/") {}
2039};
2040
2041TEST_F(Vp9SettingsTestWith2SL3TLFlag, VerifySettings) {
2042 const int kNumSpatialLayers = 2;
2043 const int kNumTemporalLayers = 3;
2044 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
2045}
2046
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002047TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruse) {
Erik SprĂ¥ngefbde372015-04-29 16:21:28 +02002048 TestCpuAdaptation(true, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002049}
2050
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002051TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenDisabled) {
Erik SprĂ¥ngefbde372015-04-29 16:21:28 +02002052 TestCpuAdaptation(false, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002053}
2054
Erik SprĂ¥ngefbde372015-04-29 16:21:28 +02002055TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenScreensharing) {
2056 TestCpuAdaptation(true, true);
2057}
2058
perkj2d5f0912016-02-29 00:04:41 -08002059TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruseAndChangeResolution) {
2060 cricket::VideoCodec codec = kVp8Codec720p;
2061 cricket::VideoSendParameters parameters;
2062 parameters.codecs.push_back(codec);
2063
2064 MediaConfig media_config = MediaConfig();
2065 channel_.reset(
2066 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
2067 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2068
2069 AddSendStream();
2070
2071 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002072 ASSERT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
perkj2d5f0912016-02-29 00:04:41 -08002073 ASSERT_EQ(cricket::CS_RUNNING,
2074 capturer.Start(capturer.GetSupportedFormats()->front()));
2075 ASSERT_TRUE(channel_->SetSend(true));
2076
2077 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2078 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
2079 webrtc::LoadObserver* overuse_callback =
2080 send_stream->GetConfig().overuse_callback;
2081 ASSERT_TRUE(overuse_callback != NULL);
2082
2083 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2084 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2085 EXPECT_EQ(1280, send_stream->GetLastWidth());
2086 EXPECT_EQ(720, send_stream->GetLastHeight());
2087
2088 // Trigger overuse.
2089 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
2090 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2091 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
2092 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2093 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2094
2095 // Trigger overuse again.
2096 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
2097 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2098 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
2099 EXPECT_EQ(1280 * 2 / 4, send_stream->GetLastWidth());
2100 EXPECT_EQ(720 * 2 / 4, send_stream->GetLastHeight());
2101
Per766ad3b2016-04-05 15:23:49 +02002102 // Trigger overuse again. This should not decrease the resolution since we
2103 // should only adapt the resolution down max two steps.
2104 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
2105 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2106 EXPECT_EQ(4, send_stream->GetNumberOfSwappedFrames());
2107 EXPECT_EQ(1280 * 2 / 4, send_stream->GetLastWidth());
2108 EXPECT_EQ(720 * 2 / 4, send_stream->GetLastHeight());
2109
perkj2d5f0912016-02-29 00:04:41 -08002110 // Change input resolution.
2111 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
Per766ad3b2016-04-05 15:23:49 +02002112 EXPECT_EQ(5, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002113 EXPECT_EQ(1284 / 2, send_stream->GetLastWidth());
2114 EXPECT_EQ(724 / 2, send_stream->GetLastHeight());
2115
2116 // Trigger underuse which should go back up in resolution.
2117 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse);
2118 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
Per766ad3b2016-04-05 15:23:49 +02002119 EXPECT_EQ(6, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002120 EXPECT_EQ(1284 * 3 / 4, send_stream->GetLastWidth());
2121 EXPECT_EQ(724 * 3 / 4, send_stream->GetLastHeight());
2122
2123 // Trigger underuse which should go back up in resolution.
2124 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse);
2125 EXPECT_TRUE(capturer.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
Per766ad3b2016-04-05 15:23:49 +02002126 EXPECT_EQ(7, send_stream->GetNumberOfSwappedFrames());
perkj2d5f0912016-02-29 00:04:41 -08002127 EXPECT_EQ(1284, send_stream->GetLastWidth());
2128 EXPECT_EQ(724, send_stream->GetLastHeight());
2129
deadbeef5a4a75a2016-06-02 16:23:38 -07002130 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkj2d5f0912016-02-29 00:04:41 -08002131}
2132
Per766ad3b2016-04-05 15:23:49 +02002133TEST_F(WebRtcVideoChannel2Test, PreviousAdaptationDoesNotApplyToScreenshare) {
2134 cricket::VideoCodec codec = kVp8Codec720p;
2135 cricket::VideoSendParameters parameters;
2136 parameters.codecs.push_back(codec);
2137
2138 MediaConfig media_config = MediaConfig();
2139 channel_.reset(
2140 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
2141 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2142
2143 AddSendStream();
2144
2145 cricket::FakeVideoCapturer capturer;
Per766ad3b2016-04-05 15:23:49 +02002146 ASSERT_EQ(cricket::CS_RUNNING,
2147 capturer.Start(capturer.GetSupportedFormats()->front()));
2148 ASSERT_TRUE(channel_->SetSend(true));
2149 cricket::VideoOptions camera_options;
deadbeef5a4a75a2016-06-02 16:23:38 -07002150 channel_->SetVideoSend(last_ssrc_, true /* enable */, &camera_options,
2151 &capturer);
Per766ad3b2016-04-05 15:23:49 +02002152
2153 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2154 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
2155 webrtc::LoadObserver* overuse_callback =
2156 send_stream->GetConfig().overuse_callback;
2157 ASSERT_TRUE(overuse_callback != NULL);
2158
2159 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2160 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2161 EXPECT_EQ(1280, send_stream->GetLastWidth());
2162 EXPECT_EQ(720, send_stream->GetLastHeight());
2163
2164 // Trigger overuse.
2165 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
2166 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2167 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
2168 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2169 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2170
2171 // Switch to screen share. Expect no CPU adaptation.
2172 cricket::FakeVideoCapturer screen_share(true);
2173 ASSERT_EQ(cricket::CS_RUNNING,
2174 screen_share.Start(screen_share.GetSupportedFormats()->front()));
Per766ad3b2016-04-05 15:23:49 +02002175 cricket::VideoOptions screenshare_options;
2176 screenshare_options.is_screencast = rtc::Optional<bool>(true);
deadbeef5a4a75a2016-06-02 16:23:38 -07002177 channel_->SetVideoSend(last_ssrc_, true /* enable */, &screenshare_options,
2178 &screen_share);
Per766ad3b2016-04-05 15:23:49 +02002179 EXPECT_TRUE(screen_share.CaptureCustomFrame(1284, 724, cricket::FOURCC_I420));
2180 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
2181 EXPECT_EQ(1284, send_stream->GetLastWidth());
2182 EXPECT_EQ(724, send_stream->GetLastHeight());
2183
2184 // Switch back to the normal capturer. Expect the frame to be CPU adapted.
deadbeef5a4a75a2016-06-02 16:23:38 -07002185 channel_->SetVideoSend(last_ssrc_, true /* enable */, &camera_options,
2186 &capturer);
Per766ad3b2016-04-05 15:23:49 +02002187 EXPECT_TRUE(capturer.CaptureCustomFrame(1280, 720, cricket::FOURCC_I420));
2188 EXPECT_EQ(4, send_stream->GetNumberOfSwappedFrames());
2189 EXPECT_EQ(1280 * 3 / 4, send_stream->GetLastWidth());
2190 EXPECT_EQ(720 * 3 / 4, send_stream->GetLastHeight());
2191
deadbeef5a4a75a2016-06-02 16:23:38 -07002192 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Per766ad3b2016-04-05 15:23:49 +02002193}
2194
Erik SprĂ¥ngefbde372015-04-29 16:21:28 +02002195void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse,
2196 bool is_screenshare) {
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002197 cricket::VideoCodec codec = kVp8Codec720p;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002198 cricket::VideoSendParameters parameters;
2199 parameters.codecs.push_back(codec);
nisse51542be2016-02-12 02:27:06 -08002200
2201 MediaConfig media_config = MediaConfig();
Peter Boströme4328002015-04-14 22:45:29 +02002202 if (!enable_overuse) {
nisse0db023a2016-03-01 04:29:59 -08002203 media_config.video.enable_cpu_overuse_detection = false;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002204 }
nisse51542be2016-02-12 02:27:06 -08002205 channel_.reset(
2206 engine_.CreateChannel(fake_call_.get(), media_config, VideoOptions()));
2207
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002208 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002209
2210 AddSendStream();
2211
deadbeef5a4a75a2016-06-02 16:23:38 -07002212 cricket::FakeVideoCapturer capturer;
nisse05103312016-03-16 02:22:50 -07002213 VideoOptions options;
2214 options.is_screencast = rtc::Optional<bool>(is_screenshare);
deadbeef5a4a75a2016-06-02 16:23:38 -07002215 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options, &capturer));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002216 EXPECT_EQ(cricket::CS_RUNNING,
2217 capturer.Start(capturer.GetSupportedFormats()->front()));
2218
2219 EXPECT_TRUE(channel_->SetSend(true));
2220
2221 // Trigger overuse.
solenberge5269742015-09-08 05:13:22 -07002222 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2223 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002224 webrtc::LoadObserver* overuse_callback =
solenberge5269742015-09-08 05:13:22 -07002225 send_stream->GetConfig().overuse_callback;
perkj2d5f0912016-02-29 00:04:41 -08002226
2227 if (!enable_overuse) {
2228 ASSERT_TRUE(overuse_callback == NULL);
2229
2230 EXPECT_TRUE(capturer.CaptureFrame());
2231 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2232
2233 EXPECT_EQ(codec.width, send_stream->GetLastWidth());
2234 EXPECT_EQ(codec.height, send_stream->GetLastHeight());
2235
deadbeef5a4a75a2016-06-02 16:23:38 -07002236 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
perkj2d5f0912016-02-29 00:04:41 -08002237 return;
2238 }
2239
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002240 ASSERT_TRUE(overuse_callback != NULL);
perkj2d5f0912016-02-29 00:04:41 -08002241 EXPECT_TRUE(capturer.CaptureFrame());
2242 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002243 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
2244
2245 EXPECT_TRUE(capturer.CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -08002246 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002247
perkj2d5f0912016-02-29 00:04:41 -08002248 if (is_screenshare) {
2249 // Do not adapt screen share.
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002250 EXPECT_EQ(codec.width, send_stream->GetLastWidth());
2251 EXPECT_EQ(codec.height, send_stream->GetLastHeight());
perkj2d5f0912016-02-29 00:04:41 -08002252 } else {
2253 EXPECT_LT(send_stream->GetLastWidth(), codec.width);
2254 EXPECT_LT(send_stream->GetLastHeight(), codec.height);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002255 }
2256
2257 // Trigger underuse which should go back to normal resolution.
2258 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse);
2259 EXPECT_TRUE(capturer.CaptureFrame());
perkj2d5f0912016-02-29 00:04:41 -08002260 EXPECT_EQ(3, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002261
2262 EXPECT_EQ(codec.width, send_stream->GetLastWidth());
2263 EXPECT_EQ(codec.height, send_stream->GetLastHeight());
2264
deadbeef5a4a75a2016-06-02 16:23:38 -07002265 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002266}
2267
magjedb09b6602015-10-01 03:02:44 -07002268TEST_F(WebRtcVideoChannel2Test, EstimatesNtpStartTimeCorrectly) {
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002269 // Start at last timestamp to verify that wraparounds are estimated correctly.
2270 static const uint32_t kInitialTimestamp = 0xFFFFFFFFu;
2271 static const int64_t kInitialNtpTimeMs = 1247891230;
2272 static const int kFrameOffsetMs = 20;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002273 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002274
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002275 FakeVideoReceiveStream* stream = AddRecvStream();
2276 cricket::FakeVideoRenderer renderer;
nisse08582ff2016-02-04 01:24:52 -08002277 EXPECT_TRUE(channel_->SetSink(last_ssrc_, &renderer));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002278
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07002279 webrtc::VideoFrame video_frame;
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002280 CreateBlackFrame(&video_frame, 4, 4);
2281 video_frame.set_timestamp(kInitialTimestamp);
2282 // Initial NTP time is not available on the first frame, but should still be
2283 // able to be estimated.
nisseeb83a1a2016-03-21 01:27:56 -07002284 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002285
2286 EXPECT_EQ(1, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002287
2288 // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which
2289 // triggers a constant-overflow warning, hence we're calculating it explicitly
2290 // here.
2291 video_frame.set_timestamp(kFrameOffsetMs * 90 - 1);
2292 video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs);
nisseeb83a1a2016-03-21 01:27:56 -07002293 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002294
2295 EXPECT_EQ(2, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002296
2297 // Verify that NTP time has been correctly deduced.
2298 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002299 ASSERT_TRUE(channel_->GetStats(&info));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00002300 ASSERT_EQ(1u, info.receivers.size());
2301 EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002302}
2303
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002304TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002305 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002306
2307 VideoCodec codec;
2308 EXPECT_TRUE(channel_->GetSendCodec(&codec));
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00002309 EXPECT_TRUE(codec.Matches(engine_.codecs()[0]));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002310
2311 // Using a RTX setup to verify that the default RTX payload type is good.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002312 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
2313 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002314 FakeVideoSendStream* stream = AddSendStream(
2315 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
perkj26091b12016-09-01 01:17:40 -07002316 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002317
2318 // Make sure NACK and FEC are enabled on the correct payload types.
2319 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
2320 EXPECT_EQ(default_ulpfec_codec_.id, config.rtp.fec.ulpfec_payload_type);
2321 EXPECT_EQ(default_red_codec_.id, config.rtp.fec.red_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002322
2323 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
2324 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
Shao Changbine62202f2015-04-21 20:24:50 +08002325 VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002326 // TODO(juberti): Check RTCP, PLI, TMMBR.
2327}
2328
2329TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002330 cricket::VideoSendParameters parameters;
2331 parameters.codecs.push_back(kVp8Codec);
2332 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002333
2334 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07002335 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002336
2337 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type);
2338 EXPECT_EQ(-1, config.rtp.fec.red_payload_type);
2339}
2340
2341TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002342 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002343 cricket::VideoSendParameters parameters;
deadbeef67cf2c12016-04-13 10:07:16 -07002344 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002345 parameters.codecs.push_back(rtx_codec);
2346 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002347 << "RTX codec without associated payload type should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002348}
2349
2350TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002351 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002352 cricket::VideoSendParameters parameters;
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002353 cricket::VideoCodec rtx_codec =
2354 cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002355 parameters.codecs.push_back(kVp8Codec);
2356 parameters.codecs.push_back(rtx_codec);
2357 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002358
2359 cricket::VideoCodec rtx_codec2 =
2360 cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id + 1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002361 parameters.codecs.pop_back();
2362 parameters.codecs.push_back(rtx_codec2);
2363 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002364 << "RTX without matching video codec should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002365}
2366
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002367TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002368 cricket::VideoSendParameters parameters;
2369 parameters.codecs.push_back(kVp8Codec);
2370 parameters.codecs.push_back(kUlpfecCodec);
2371 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002372
2373 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07002374 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002375
2376 EXPECT_EQ(kUlpfecCodec.id, config.rtp.fec.ulpfec_payload_type);
2377
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002378 parameters.codecs.pop_back();
2379 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002380 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002381 ASSERT_TRUE(stream != NULL);
perkj26091b12016-09-01 01:17:40 -07002382 config = stream->GetConfig().Copy();
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002383 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type)
2384 << "SetSendCodec without FEC should disable current FEC.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002385}
2386
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002387TEST_F(WebRtcVideoChannel2Test, SetSendCodecsChangesExistingStreams) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002388 cricket::VideoSendParameters parameters;
2389 parameters.codecs.push_back(kVp8Codec720p);
2390 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002391 channel_->SetSend(true);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002392
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002393 FakeVideoSendStream* stream = AddSendStream();
2394
2395 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002396 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002397 EXPECT_EQ(cricket::CS_RUNNING,
2398 capturer.Start(capturer.GetSupportedFormats()->front()));
2399 EXPECT_TRUE(capturer.CaptureFrame());
2400
2401 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002402 EXPECT_EQ(kVp8Codec720p.width, streams[0].width);
2403 EXPECT_EQ(kVp8Codec720p.height, streams[0].height);
2404
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002405 parameters.codecs.clear();
2406 parameters.codecs.push_back(kVp8Codec360p);
2407 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002408 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00002409 EXPECT_EQ(kVp8Codec360p.width, streams[0].width);
2410 EXPECT_EQ(kVp8Codec360p.height, streams[0].height);
deadbeef5a4a75a2016-06-02 16:23:38 -07002411 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002412}
2413
pbos@webrtc.org00873182014-11-25 14:03:34 +00002414TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithBitrates) {
2415 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
2416 200000);
2417}
2418
pbos@webrtc.orga5f6fb52015-03-23 22:29:39 +00002419TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithHighMaxBitrate) {
2420 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
2421 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
2422 ASSERT_EQ(1u, streams.size());
2423 EXPECT_EQ(10000000, streams[0].max_bitrate_bps);
2424}
2425
pbos@webrtc.org00873182014-11-25 14:03:34 +00002426TEST_F(WebRtcVideoChannel2Test,
2427 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
2428 SetSendCodecsShouldWorkForBitrates(
2429 "", 0, "", -1, "", -1);
2430}
2431
2432TEST_F(WebRtcVideoChannel2Test, SetSendCodecsCapsMinAndStartBitrate) {
2433 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002434}
2435
2436TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectsMaxLessThanMinBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002437 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "300";
2438 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "200";
2439 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002440}
2441
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07002442// Test that when both the codec-specific bitrate params and max_bandwidth_bps
2443// are present in the same send parameters, the settings are combined correctly.
2444TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithBitratesAndMaxSendBandwidth) {
2445 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
2446 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
2447 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
2448 send_parameters_.max_bandwidth_bps = 400000;
2449 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2450 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2451 EXPECT_EQ(200000, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2452 // We expect max_bandwidth_bps to take priority, if set.
2453 EXPECT_EQ(400000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2454
2455 // Decrease max_bandwidth_bps.
2456 send_parameters_.max_bandwidth_bps = 350000;
2457 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2458 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2459 // Since the codec isn't changing, start_bitrate_bps should be -1.
2460 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2461 EXPECT_EQ(350000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2462
2463 // Now try again with the values flipped around.
2464 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
2465 send_parameters_.max_bandwidth_bps = 300000;
2466 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2467 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2468 EXPECT_EQ(200000, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2469 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2470
2471 // If we change the codec max, max_bandwidth_bps should still apply.
2472 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
2473 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2474 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
2475 EXPECT_EQ(200000, fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
2476 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2477}
2478
pbos@webrtc.org00873182014-11-25 14:03:34 +00002479TEST_F(WebRtcVideoChannel2Test,
2480 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
2481 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
2482 200000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002483 send_parameters_.max_bandwidth_bps = 300000;
2484 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01002485 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002486 << "Setting max bitrate should keep previous min bitrate.";
Stefan Holmere5904162015-03-26 11:11:06 +01002487 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.start_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002488 << "Setting max bitrate should not reset start bitrate.";
Stefan Holmere5904162015-03-26 11:11:06 +01002489 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002490}
2491
2492TEST_F(WebRtcVideoChannel2Test, SetMaxSendBandwidthShouldBeRemovable) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002493 send_parameters_.max_bandwidth_bps = 300000;
2494 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01002495 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002496 // <= 0 means disable (infinite) max bitrate.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002497 send_parameters_.max_bandwidth_bps = 0;
2498 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Stefan Holmere5904162015-03-26 11:11:06 +01002499 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.max_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002500 << "Setting zero max bitrate did not reset start bitrate.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002501}
2502
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002503TEST_F(WebRtcVideoChannel2Test, SetMaxSendBitrateCanIncreaseSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002504 cricket::VideoSendParameters parameters;
2505 parameters.codecs.push_back(kVp8Codec720p);
2506 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002507 channel_->SetSend(true);
2508
2509 FakeVideoSendStream* stream = AddSendStream();
2510
Peter Boström3afc8c42016-01-27 16:45:21 +01002511 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002512 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
Peter Boström3afc8c42016-01-27 16:45:21 +01002513 EXPECT_EQ(cricket::CS_RUNNING,
2514 capturer.Start(capturer.GetSupportedFormats()->front()));
2515
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002516 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
2517 int initial_max_bitrate_bps = streams[0].max_bitrate_bps;
2518 EXPECT_GT(initial_max_bitrate_bps, 0);
2519
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002520 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
2521 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01002522 // Insert a frame to update the encoder config.
2523 EXPECT_TRUE(capturer.CaptureFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002524 streams = stream->GetVideoStreams();
2525 EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps);
deadbeef5a4a75a2016-06-02 16:23:38 -07002526 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002527}
2528
2529TEST_F(WebRtcVideoChannel2Test,
2530 SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002531 cricket::VideoSendParameters parameters;
2532 parameters.codecs.push_back(kVp8Codec720p);
2533 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002534 channel_->SetSend(true);
2535
2536 FakeVideoSendStream* stream = AddSendStream(
2537 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
2538
2539 // Send a frame to make sure this scales up to >1 stream (simulcast).
2540 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07002541 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], true, nullptr, &capturer));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002542 EXPECT_EQ(cricket::CS_RUNNING,
2543 capturer.Start(capturer.GetSupportedFormats()->front()));
2544 EXPECT_TRUE(capturer.CaptureFrame());
2545
2546 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
2547 ASSERT_GT(streams.size(), 1u)
2548 << "Without simulcast this test doesn't make sense.";
pbosbe16f792015-10-16 12:49:39 -07002549 int initial_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002550 EXPECT_GT(initial_max_bitrate_bps, 0);
2551
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002552 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
2553 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01002554 // Insert a frame to update the encoder config.
2555 EXPECT_TRUE(capturer.CaptureFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002556 streams = stream->GetVideoStreams();
pbosbe16f792015-10-16 12:49:39 -07002557 int increased_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002558 EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps);
2559
deadbeef5a4a75a2016-06-02 16:23:38 -07002560 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], true, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002561}
2562
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002563TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMaxQuantization) {
2564 static const char* kMaxQuantization = "21";
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002565 cricket::VideoSendParameters parameters;
2566 parameters.codecs.push_back(kVp8Codec);
2567 parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
2568 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00002569 EXPECT_EQ(static_cast<unsigned int>(atoi(kMaxQuantization)),
2570 AddSendStream()->GetVideoStreams().back().max_qp);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002571
2572 VideoCodec codec;
2573 EXPECT_TRUE(channel_->GetSendCodec(&codec));
2574 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
2575}
2576
2577TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadDimensions) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002578 cricket::VideoSendParameters parameters;
2579 parameters.codecs.push_back(kVp8Codec);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002580
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002581 parameters.codecs[0].width = 0;
2582 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002583 << "Codec set though codec width is zero.";
2584
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002585 parameters.codecs[0].width = kVp8Codec.width;
2586 parameters.codecs[0].height = 0;
2587 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002588 << "Codec set though codec height is zero.";
2589}
2590
2591TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) {
2592 // TODO(pbos): Should we only allow the dynamic range?
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002593 static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002594 cricket::VideoSendParameters parameters;
2595 parameters.codecs.push_back(kVp8Codec);
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002596 for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002597 parameters.codecs[0].id = kIncorrectPayloads[i];
2598 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pkasting@chromium.orgd3245462015-02-23 21:28:22 +00002599 << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002600 }
2601}
2602
2603TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptAllValidPayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002604 cricket::VideoSendParameters parameters;
2605 parameters.codecs.push_back(kVp8Codec);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002606 for (int payload_type = 0; payload_type <= 127; ++payload_type) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002607 parameters.codecs[0].id = payload_type;
2608 EXPECT_TRUE(channel_->SetSendParameters(parameters))
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002609 << "Payload type '" << payload_type << "' rejected.";
2610 }
2611}
2612
deadbeef67cf2c12016-04-13 10:07:16 -07002613// Test that setting the a different set of codecs but with an identical front
2614// codec doesn't result in the stream being recreated.
2615// This may happen when a subsequent negotiation includes fewer codecs, as a
2616// result of one of the codecs being rejected.
2617TEST_F(WebRtcVideoChannel2Test,
2618 SetSendCodecsIdenticalFirstCodecDoesntRecreateStream) {
2619 cricket::VideoSendParameters parameters1;
2620 parameters1.codecs.push_back(kVp8Codec);
2621 parameters1.codecs.push_back(kVp9Codec);
2622 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
2623
2624 AddSendStream();
2625 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2626
2627 cricket::VideoSendParameters parameters2;
2628 parameters2.codecs.push_back(kVp8Codec);
2629 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
2630 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2631}
2632
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002633TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithOnlyVp8) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002634 cricket::VideoRecvParameters parameters;
2635 parameters.codecs.push_back(kVp8Codec);
2636 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002637}
2638
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002639// Test that we set our inbound RTX codecs properly.
2640TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002641 cricket::VideoRecvParameters parameters;
2642 parameters.codecs.push_back(kVp8Codec);
deadbeef67cf2c12016-04-13 10:07:16 -07002643 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002644 parameters.codecs.push_back(rtx_codec);
2645 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002646 << "RTX codec without associated payload should be rejected.";
2647
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002648 parameters.codecs[1].SetParam("apt", kVp8Codec.id + 1);
2649 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002650 << "RTX codec with invalid associated payload type should be rejected.";
2651
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002652 parameters.codecs[1].SetParam("apt", kVp8Codec.id);
2653 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002654
deadbeef67cf2c12016-04-13 10:07:16 -07002655 cricket::VideoCodec rtx_codec2(97, "rtx", 0, 0, 0);
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002656 rtx_codec2.SetParam("apt", rtx_codec.id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002657 parameters.codecs.push_back(rtx_codec2);
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002658
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002659 EXPECT_FALSE(channel_->SetRecvParameters(parameters)) <<
2660 "RTX codec with another RTX as associated payload type should be "
2661 "rejected.";
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002662}
2663
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002664TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentPayloadType) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002665 cricket::VideoRecvParameters parameters;
2666 parameters.codecs.push_back(kVp8Codec);
2667 parameters.codecs[0].id = 99;
2668 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002669}
2670
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00002671TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsAcceptDefaultCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002672 cricket::VideoRecvParameters parameters;
2673 parameters.codecs = engine_.codecs();
2674 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00002675
2676 FakeVideoReceiveStream* stream = AddRecvStream();
Tommi733b5472016-06-10 17:58:01 +02002677 const webrtc::VideoReceiveStream::Config& config = stream->GetConfig();
pbos@webrtc.org776e6f22014-10-29 15:28:39 +00002678 EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].payload_name);
2679 EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002680}
2681
2682TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002683 cricket::VideoRecvParameters parameters;
2684 parameters.codecs.push_back(kVp8Codec);
deadbeef67cf2c12016-04-13 10:07:16 -07002685 parameters.codecs.push_back(VideoCodec(101, "WTF3", 640, 400, 30));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002686 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002687}
2688
2689// TODO(pbos): Enable VP9 through external codec support
2690TEST_F(WebRtcVideoChannel2Test,
2691 DISABLED_SetRecvCodecsAcceptsMultipleVideoCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002692 cricket::VideoRecvParameters parameters;
2693 parameters.codecs.push_back(kVp8Codec);
2694 parameters.codecs.push_back(kVp9Codec);
2695 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002696}
2697
2698TEST_F(WebRtcVideoChannel2Test,
2699 DISABLED_SetRecvCodecsSetsFecForAllVideoCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002700 cricket::VideoRecvParameters parameters;
2701 parameters.codecs.push_back(kVp8Codec);
2702 parameters.codecs.push_back(kVp9Codec);
2703 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002704 FAIL(); // TODO(pbos): Verify that the FEC parameters are set for all codecs.
2705}
2706
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002707TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002708 cricket::VideoSendParameters send_parameters;
2709 send_parameters.codecs.push_back(kVp8Codec);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002710 send_parameters.codecs.push_back(kRedCodec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002711 send_parameters.codecs.push_back(kUlpfecCodec);
2712 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002713
2714 FakeVideoReceiveStream* stream = AddRecvStream();
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002715
Tommi733b5472016-06-10 17:58:01 +02002716 EXPECT_EQ(kUlpfecCodec.id, stream->GetConfig().rtp.fec.ulpfec_payload_type);
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002717
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002718 cricket::VideoRecvParameters recv_parameters;
2719 recv_parameters.codecs.push_back(kVp8Codec);
2720 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002721 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002722 ASSERT_TRUE(stream != NULL);
Tommi733b5472016-06-10 17:58:01 +02002723 EXPECT_EQ(-1, stream->GetConfig().rtp.fec.ulpfec_payload_type)
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002724 << "SetSendCodec without FEC should disable current FEC.";
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002725}
2726
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002727TEST_F(WebRtcVideoChannel2Test, SetSendParamsWithoutFecDisablesReceivingFec) {
2728 FakeVideoReceiveStream* stream = AddRecvStream();
Tommi733b5472016-06-10 17:58:01 +02002729 EXPECT_EQ(kUlpfecCodec.id, stream->GetConfig().rtp.fec.ulpfec_payload_type);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002730
2731 cricket::VideoRecvParameters recv_parameters;
2732 recv_parameters.codecs.push_back(kVp8Codec);
2733 recv_parameters.codecs.push_back(kRedCodec);
2734 recv_parameters.codecs.push_back(kUlpfecCodec);
2735 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
2736 stream = fake_call_->GetVideoReceiveStreams()[0];
2737 ASSERT_TRUE(stream != NULL);
Tommi733b5472016-06-10 17:58:01 +02002738 EXPECT_EQ(kUlpfecCodec.id, stream->GetConfig().rtp.fec.ulpfec_payload_type)
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002739 << "FEC should be enabled on the recieve stream.";
2740
2741 cricket::VideoSendParameters send_parameters;
2742 send_parameters.codecs.push_back(kVp8Codec);
2743 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
2744 stream = fake_call_->GetVideoReceiveStreams()[0];
Tommi733b5472016-06-10 17:58:01 +02002745 EXPECT_EQ(-1, stream->GetConfig().rtp.fec.ulpfec_payload_type)
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002746 << "FEC should have been disabled when we know the other side won't do "
2747 "FEC.";
2748
2749 send_parameters.codecs.push_back(kRedCodec);
2750 send_parameters.codecs.push_back(kUlpfecCodec);
2751 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
2752 stream = fake_call_->GetVideoReceiveStreams()[0];
Tommi733b5472016-06-10 17:58:01 +02002753 EXPECT_EQ(kUlpfecCodec.id, stream->GetConfig().rtp.fec.ulpfec_payload_type)
Stefan Holmer2b1f6512016-05-17 16:33:30 +02002754 << "FEC should be enabled on the recieve stream.";
2755}
2756
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002757TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectDuplicateFecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002758 cricket::VideoRecvParameters parameters;
2759 parameters.codecs.push_back(kVp8Codec);
2760 parameters.codecs.push_back(kRedCodec);
2761 parameters.codecs[1].id = parameters.codecs[0].id;
2762 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002763}
2764
2765TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectDuplicateCodecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002766 cricket::VideoRecvParameters parameters;
2767 parameters.codecs.push_back(kVp8Codec);
2768 parameters.codecs.push_back(kVp9Codec);
2769 parameters.codecs[1].id = parameters.codecs[0].id;
2770 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002771}
2772
2773TEST_F(WebRtcVideoChannel2Test,
2774 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002775 cricket::VideoRecvParameters parameters;
2776 parameters.codecs.push_back(kVp8Codec);
2777 parameters.codecs.push_back(kVp8Codec);
2778 parameters.codecs[1].id += 1;
2779 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002780}
2781
deadbeef67cf2c12016-04-13 10:07:16 -07002782// Test that setting the same codecs but with a different order
deadbeef874ca3a2015-08-20 17:19:20 -07002783// doesn't result in the stream being recreated.
2784TEST_F(WebRtcVideoChannel2Test,
deadbeef67cf2c12016-04-13 10:07:16 -07002785 SetRecvCodecsDifferentOrderDoesntRecreateStream) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002786 cricket::VideoRecvParameters parameters1;
2787 parameters1.codecs.push_back(kVp8Codec);
2788 parameters1.codecs.push_back(kRedCodec);
2789 EXPECT_TRUE(channel_->SetRecvParameters(parameters1));
deadbeef874ca3a2015-08-20 17:19:20 -07002790
2791 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2792 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2793
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002794 cricket::VideoRecvParameters parameters2;
2795 parameters2.codecs.push_back(kRedCodec);
2796 parameters2.codecs.push_back(kVp8Codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002797 EXPECT_TRUE(channel_->SetRecvParameters(parameters2));
deadbeef874ca3a2015-08-20 17:19:20 -07002798 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2799}
2800
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002801TEST_F(WebRtcVideoChannel2Test, SendStreamNotSendingByDefault) {
2802 EXPECT_FALSE(AddSendStream()->IsSending());
2803}
2804
pbos@webrtc.org85f42942014-07-22 09:14:58 +00002805TEST_F(WebRtcVideoChannel2Test, ReceiveStreamReceivingByDefault) {
2806 EXPECT_TRUE(AddRecvStream()->IsReceiving());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002807}
2808
2809TEST_F(WebRtcVideoChannel2Test, SetSend) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +00002810 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002811 EXPECT_FALSE(stream->IsSending());
2812
2813 // false->true
2814 EXPECT_TRUE(channel_->SetSend(true));
2815 EXPECT_TRUE(stream->IsSending());
2816 // true->true
2817 EXPECT_TRUE(channel_->SetSend(true));
2818 EXPECT_TRUE(stream->IsSending());
2819 // true->false
2820 EXPECT_TRUE(channel_->SetSend(false));
2821 EXPECT_FALSE(stream->IsSending());
2822 // false->false
2823 EXPECT_TRUE(channel_->SetSend(false));
2824 EXPECT_FALSE(stream->IsSending());
2825
2826 EXPECT_TRUE(channel_->SetSend(true));
2827 FakeVideoSendStream* new_stream = AddSendStream();
2828 EXPECT_TRUE(new_stream->IsSending())
2829 << "Send stream created after SetSend(true) not sending initially.";
2830}
2831
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00002832// This test verifies DSCP settings are properly applied on video media channel.
2833TEST_F(WebRtcVideoChannel2Test, TestSetDscpOptions) {
kwiberg686a8ef2016-02-26 03:00:35 -08002834 std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00002835 new cricket::FakeNetworkInterface);
nisse51542be2016-02-12 02:27:06 -08002836 MediaConfig config;
kwiberg686a8ef2016-02-26 03:00:35 -08002837 std::unique_ptr<VideoMediaChannel> channel;
nisse51542be2016-02-12 02:27:06 -08002838
2839 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
2840 channel->SetInterface(network_interface.get());
2841 // Default value when DSCP is disabled should be DSCP_DEFAULT.
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00002842 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
nisse51542be2016-02-12 02:27:06 -08002843
2844 config.enable_dscp = true;
2845 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
2846 channel->SetInterface(network_interface.get());
2847 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
2848
2849 // Verify that setting the option to false resets the
2850 // DiffServCodePoint.
2851 config.enable_dscp = false;
2852 channel.reset(engine_.CreateChannel(call_.get(), config, VideoOptions()));
2853 channel->SetInterface(network_interface.get());
2854 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002855}
2856
deadbeef13871492015-12-09 12:37:51 -08002857// This test verifies that the RTCP reduced size mode is properly applied to
2858// send video streams.
2859TEST_F(WebRtcVideoChannel2Test, TestSetSendRtcpReducedSize) {
2860 // Create stream, expecting that default mode is "compound".
2861 FakeVideoSendStream* stream1 = AddSendStream();
2862 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
2863
2864 // Now enable reduced size mode.
2865 send_parameters_.rtcp.reduced_size = true;
2866 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2867 stream1 = fake_call_->GetVideoSendStreams()[0];
2868 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
2869
2870 // Create a new stream and ensure it picks up the reduced size mode.
2871 FakeVideoSendStream* stream2 = AddSendStream();
2872 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
2873}
2874
2875// This test verifies that the RTCP reduced size mode is properly applied to
2876// receive video streams.
2877TEST_F(WebRtcVideoChannel2Test, TestSetRecvRtcpReducedSize) {
2878 // Create stream, expecting that default mode is "compound".
2879 FakeVideoReceiveStream* stream1 = AddRecvStream();
2880 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
2881
2882 // Now enable reduced size mode.
Taylor Brandstetter5f0b83b2016-03-18 15:02:07 -07002883 // TODO(deadbeef): Once "recv_parameters" becomes "receiver_parameters",
2884 // the reduced_size flag should come from that.
2885 send_parameters_.rtcp.reduced_size = true;
2886 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
deadbeef13871492015-12-09 12:37:51 -08002887 stream1 = fake_call_->GetVideoReceiveStreams()[0];
2888 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
2889
2890 // Create a new stream and ensure it picks up the reduced size mode.
2891 FakeVideoReceiveStream* stream2 = AddRecvStream();
2892 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
2893}
2894
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002895TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) {
skvlad7a43d252016-03-22 15:32:27 -07002896 EXPECT_EQ(webrtc::kNetworkUp,
2897 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
2898 EXPECT_EQ(webrtc::kNetworkUp,
2899 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002900
2901 channel_->OnReadyToSend(false);
skvlad7a43d252016-03-22 15:32:27 -07002902 EXPECT_EQ(webrtc::kNetworkDown,
2903 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
2904 EXPECT_EQ(webrtc::kNetworkUp,
2905 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002906
2907 channel_->OnReadyToSend(true);
skvlad7a43d252016-03-22 15:32:27 -07002908 EXPECT_EQ(webrtc::kNetworkUp,
2909 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
2910 EXPECT_EQ(webrtc::kNetworkUp,
2911 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002912}
2913
Peter Boström74d9ed72015-03-26 16:28:31 +01002914TEST_F(WebRtcVideoChannel2Test, GetStatsReportsSentCodecName) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002915 cricket::VideoSendParameters parameters;
2916 parameters.codecs.push_back(kVp8Codec);
2917 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström74d9ed72015-03-26 16:28:31 +01002918
2919 AddSendStream();
2920
2921 cricket::VideoMediaInfo info;
2922 ASSERT_TRUE(channel_->GetStats(&info));
2923 EXPECT_EQ(kVp8Codec.name, info.senders[0].codec_name);
2924}
2925
Peter Boströmb7d9a972015-12-18 16:01:11 +01002926TEST_F(WebRtcVideoChannel2Test, GetStatsReportsEncoderImplementationName) {
2927 FakeVideoSendStream* stream = AddSendStream();
2928 webrtc::VideoSendStream::Stats stats;
2929 stats.encoder_implementation_name = "encoder_implementation_name";
2930 stream->SetStats(stats);
2931
2932 cricket::VideoMediaInfo info;
2933 ASSERT_TRUE(channel_->GetStats(&info));
2934 EXPECT_EQ(stats.encoder_implementation_name,
2935 info.senders[0].encoder_implementation_name);
2936}
2937
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00002938TEST_F(WebRtcVideoChannel2Test, GetStatsReportsCpuOveruseMetrics) {
2939 FakeVideoSendStream* stream = AddSendStream();
2940 webrtc::VideoSendStream::Stats stats;
2941 stats.avg_encode_time_ms = 13;
2942 stats.encode_usage_percent = 42;
2943 stream->SetStats(stats);
2944
2945 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002946 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00002947 EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
2948 EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
2949}
2950
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002951TEST_F(WebRtcVideoChannel2Test, GetStatsReportsUpperResolution) {
2952 FakeVideoSendStream* stream = AddSendStream();
2953 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002954 stats.substreams[17].width = 123;
2955 stats.substreams[17].height = 40;
2956 stats.substreams[42].width = 80;
2957 stats.substreams[42].height = 31;
2958 stats.substreams[11].width = 20;
2959 stats.substreams[11].height = 90;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002960 stream->SetStats(stats);
2961
2962 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002963 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002964 ASSERT_EQ(1u, info.senders.size());
2965 EXPECT_EQ(123, info.senders[0].send_frame_width);
2966 EXPECT_EQ(90, info.senders[0].send_frame_height);
2967}
2968
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00002969TEST_F(WebRtcVideoChannel2Test, GetStatsTracksAdaptationStats) {
2970 AddSendStream(cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
2971
2972 // Capture format VGA.
2973 cricket::FakeVideoCapturer video_capturer_vga;
2974 const std::vector<cricket::VideoFormat>* formats =
2975 video_capturer_vga.GetSupportedFormats();
2976 cricket::VideoFormat capture_format_vga = (*formats)[1];
2977 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_vga.Start(capture_format_vga));
deadbeef5a4a75a2016-06-02 16:23:38 -07002978 EXPECT_TRUE(
2979 channel_->SetVideoSend(kSsrcs3[0], true, nullptr, &video_capturer_vga));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00002980 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
2981
deadbeef67cf2c12016-04-13 10:07:16 -07002982 cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002983 cricket::VideoSendParameters parameters;
2984 parameters.codecs.push_back(send_codec);
2985 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00002986 EXPECT_TRUE(channel_->SetSend(true));
2987
2988 // Verify that the CpuOveruseObserver is registered and trigger downgrade.
solenberge5269742015-09-08 05:13:22 -07002989
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00002990 // Trigger overuse.
solenberge5269742015-09-08 05:13:22 -07002991 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00002992 webrtc::LoadObserver* overuse_callback =
solenberge5269742015-09-08 05:13:22 -07002993 fake_call_->GetVideoSendStreams().front()->GetConfig().overuse_callback;
2994 ASSERT_TRUE(overuse_callback != NULL);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00002995 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
2996
2997 // Capture format VGA -> adapt (OnCpuResolutionRequest downgrade) -> VGA/2.
2998 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
2999 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003000 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003001 ASSERT_EQ(1U, info.senders.size());
3002 EXPECT_EQ(1, info.senders[0].adapt_changes);
Per766ad3b2016-04-05 15:23:49 +02003003 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_CPU, info.senders[0].adapt_reason);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003004
3005 // Trigger upgrade and verify that we adapt back up to VGA.
3006 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse);
3007 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
3008 info.Clear();
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003009 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003010 ASSERT_EQ(1U, info.senders.size());
3011 EXPECT_EQ(2, info.senders[0].adapt_changes);
Per766ad3b2016-04-05 15:23:49 +02003012 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_NONE,
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003013 info.senders[0].adapt_reason);
3014
3015 // No capturer (no adapter). Adapt changes from old adapter should be kept.
deadbeef5a4a75a2016-06-02 16:23:38 -07003016 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], true, nullptr, nullptr));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003017 info.Clear();
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003018 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003019 ASSERT_EQ(1U, info.senders.size());
3020 EXPECT_EQ(2, info.senders[0].adapt_changes);
Per766ad3b2016-04-05 15:23:49 +02003021 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_NONE,
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003022 info.senders[0].adapt_reason);
3023
3024 // Set new capturer, capture format HD.
3025 cricket::FakeVideoCapturer video_capturer_hd;
3026 cricket::VideoFormat capture_format_hd = (*formats)[0];
3027 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_hd.Start(capture_format_hd));
deadbeef5a4a75a2016-06-02 16:23:38 -07003028 EXPECT_TRUE(
3029 channel_->SetVideoSend(kSsrcs3[0], true, nullptr, &video_capturer_hd));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003030 EXPECT_TRUE(video_capturer_hd.CaptureFrame());
3031
3032 // Trigger overuse, HD -> adapt (OnCpuResolutionRequest downgrade) -> HD/2.
3033 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
3034 EXPECT_TRUE(video_capturer_hd.CaptureFrame());
3035 info.Clear();
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003036 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003037 ASSERT_EQ(1U, info.senders.size());
3038 EXPECT_EQ(3, info.senders[0].adapt_changes);
Per766ad3b2016-04-05 15:23:49 +02003039 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_CPU, info.senders[0].adapt_reason);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003040
deadbeef5a4a75a2016-06-02 16:23:38 -07003041 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], true, nullptr, nullptr));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00003042}
3043
asapersson17821db2015-12-14 02:08:12 -08003044TEST_F(WebRtcVideoChannel2Test, GetStatsTracksAdaptationAndBandwidthStats) {
3045 AddSendStream(cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
3046
3047 // Capture format VGA.
3048 cricket::FakeVideoCapturer video_capturer_vga;
3049 const std::vector<cricket::VideoFormat>* formats =
3050 video_capturer_vga.GetSupportedFormats();
3051 cricket::VideoFormat capture_format_vga = (*formats)[1];
3052 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_vga.Start(capture_format_vga));
deadbeef5a4a75a2016-06-02 16:23:38 -07003053 EXPECT_TRUE(
3054 channel_->SetVideoSend(kSsrcs3[0], true, nullptr, &video_capturer_vga));
asapersson17821db2015-12-14 02:08:12 -08003055 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
3056
deadbeef67cf2c12016-04-13 10:07:16 -07003057 cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30);
asapersson17821db2015-12-14 02:08:12 -08003058 cricket::VideoSendParameters parameters;
3059 parameters.codecs.push_back(send_codec);
3060 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3061 EXPECT_TRUE(channel_->SetSend(true));
3062
3063 // Verify that the CpuOveruseObserver is registered and trigger downgrade.
asapersson17821db2015-12-14 02:08:12 -08003064
3065 // Trigger overuse -> adapt CPU.
3066 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
3067 webrtc::LoadObserver* overuse_callback =
3068 fake_call_->GetVideoSendStreams().front()->GetConfig().overuse_callback;
3069 ASSERT_TRUE(overuse_callback != NULL);
3070 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
3071 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
3072 cricket::VideoMediaInfo info;
3073 EXPECT_TRUE(channel_->GetStats(&info));
3074 ASSERT_EQ(1U, info.senders.size());
Per766ad3b2016-04-05 15:23:49 +02003075 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_CPU, info.senders[0].adapt_reason);
asapersson17821db2015-12-14 02:08:12 -08003076
3077 // Set bandwidth limitation stats for the stream -> adapt CPU + BW.
3078 webrtc::VideoSendStream::Stats stats;
3079 stats.bw_limited_resolution = true;
3080 fake_call_->GetVideoSendStreams().front()->SetStats(stats);
3081 info.Clear();
3082 EXPECT_TRUE(channel_->GetStats(&info));
3083 ASSERT_EQ(1U, info.senders.size());
Per766ad3b2016-04-05 15:23:49 +02003084 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_CPU |
3085 WebRtcVideoChannel2::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08003086 info.senders[0].adapt_reason);
3087
3088 // Trigger upgrade -> adapt BW.
3089 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse);
3090 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
3091 info.Clear();
3092 EXPECT_TRUE(channel_->GetStats(&info));
3093 ASSERT_EQ(1U, info.senders.size());
Per766ad3b2016-04-05 15:23:49 +02003094 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08003095 info.senders[0].adapt_reason);
3096
3097 // Reset bandwidth limitation state -> adapt NONE.
3098 stats.bw_limited_resolution = false;
3099 fake_call_->GetVideoSendStreams().front()->SetStats(stats);
3100 info.Clear();
3101 EXPECT_TRUE(channel_->GetStats(&info));
3102 ASSERT_EQ(1U, info.senders.size());
Per766ad3b2016-04-05 15:23:49 +02003103 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_NONE,
asapersson17821db2015-12-14 02:08:12 -08003104 info.senders[0].adapt_reason);
3105
deadbeef5a4a75a2016-06-02 16:23:38 -07003106 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], true, nullptr, nullptr));
asapersson17821db2015-12-14 02:08:12 -08003107}
3108
3109TEST_F(WebRtcVideoChannel2Test,
3110 GetStatsTranslatesBandwidthLimitedResolutionCorrectly) {
3111 FakeVideoSendStream* stream = AddSendStream();
3112 webrtc::VideoSendStream::Stats stats;
3113 stats.bw_limited_resolution = true;
3114 stream->SetStats(stats);
3115
3116 cricket::VideoMediaInfo info;
3117 EXPECT_TRUE(channel_->GetStats(&info));
3118 ASSERT_EQ(1U, info.senders.size());
Per766ad3b2016-04-05 15:23:49 +02003119 EXPECT_EQ(WebRtcVideoChannel2::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08003120 info.senders[0].adapt_reason);
3121}
3122
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003123TEST_F(WebRtcVideoChannel2Test,
3124 GetStatsTranslatesSendRtcpPacketTypesCorrectly) {
3125 FakeVideoSendStream* stream = AddSendStream();
3126 webrtc::VideoSendStream::Stats stats;
3127 stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2;
3128 stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3;
3129 stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4;
3130
3131 stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5;
3132 stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7;
3133 stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9;
3134
3135 stream->SetStats(stats);
3136
3137 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003138 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003139 EXPECT_EQ(7, info.senders[0].firs_rcvd);
3140 EXPECT_EQ(10, info.senders[0].nacks_rcvd);
3141 EXPECT_EQ(13, info.senders[0].plis_rcvd);
3142}
3143
3144TEST_F(WebRtcVideoChannel2Test,
3145 GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) {
3146 FakeVideoReceiveStream* stream = AddRecvStream();
3147 webrtc::VideoReceiveStream::Stats stats;
3148 stats.rtcp_packet_type_counts.fir_packets = 2;
3149 stats.rtcp_packet_type_counts.nack_packets = 3;
3150 stats.rtcp_packet_type_counts.pli_packets = 4;
3151 stream->SetStats(stats);
3152
3153 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003154 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00003155 EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets,
3156 info.receivers[0].firs_sent);
3157 EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets,
3158 info.receivers[0].nacks_sent);
3159 EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets,
3160 info.receivers[0].plis_sent);
3161}
3162
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003163TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesDecodeStatsCorrectly) {
3164 FakeVideoReceiveStream* stream = AddRecvStream();
3165 webrtc::VideoReceiveStream::Stats stats;
Peter Boströmb7d9a972015-12-18 16:01:11 +01003166 stats.decoder_implementation_name = "decoder_implementation_name";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003167 stats.decode_ms = 2;
3168 stats.max_decode_ms = 3;
3169 stats.current_delay_ms = 4;
3170 stats.target_delay_ms = 5;
3171 stats.jitter_buffer_ms = 6;
3172 stats.min_playout_delay_ms = 7;
3173 stats.render_delay_ms = 8;
asapersson26dd92b2016-08-30 00:45:45 -07003174 stats.width = 9;
3175 stats.height = 10;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003176 stream->SetStats(stats);
3177
3178 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003179 ASSERT_TRUE(channel_->GetStats(&info));
Peter Boströmb7d9a972015-12-18 16:01:11 +01003180 EXPECT_EQ(stats.decoder_implementation_name,
3181 info.receivers[0].decoder_implementation_name);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003182 EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
3183 EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
3184 EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
3185 EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
3186 EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
3187 EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
3188 EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
asapersson26dd92b2016-08-30 00:45:45 -07003189 EXPECT_EQ(stats.width, info.receivers[0].frame_width);
3190 EXPECT_EQ(stats.height, info.receivers[0].frame_height);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00003191}
3192
Peter Boström393347f2015-04-22 14:52:45 +02003193TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesReceivePacketStatsCorrectly) {
3194 FakeVideoReceiveStream* stream = AddRecvStream();
3195 webrtc::VideoReceiveStream::Stats stats;
3196 stats.rtp_stats.transmitted.payload_bytes = 2;
3197 stats.rtp_stats.transmitted.header_bytes = 3;
3198 stats.rtp_stats.transmitted.padding_bytes = 4;
3199 stats.rtp_stats.transmitted.packets = 5;
3200 stats.rtcp_stats.cumulative_lost = 6;
3201 stats.rtcp_stats.fraction_lost = 7;
3202 stream->SetStats(stats);
3203
3204 cricket::VideoMediaInfo info;
3205 ASSERT_TRUE(channel_->GetStats(&info));
3206 EXPECT_EQ(stats.rtp_stats.transmitted.payload_bytes +
3207 stats.rtp_stats.transmitted.header_bytes +
3208 stats.rtp_stats.transmitted.padding_bytes,
3209 info.receivers[0].bytes_rcvd);
3210 EXPECT_EQ(stats.rtp_stats.transmitted.packets,
3211 info.receivers[0].packets_rcvd);
3212 EXPECT_EQ(stats.rtcp_stats.cumulative_lost, info.receivers[0].packets_lost);
3213 EXPECT_EQ(static_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8),
3214 info.receivers[0].fraction_lost);
3215}
3216
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003217TEST_F(WebRtcVideoChannel2Test, TranslatesCallStatsCorrectly) {
3218 AddSendStream();
3219 AddSendStream();
3220 webrtc::Call::Stats stats;
3221 stats.rtt_ms = 123;
3222 fake_call_->SetStats(stats);
3223
3224 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003225 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003226 ASSERT_EQ(2u, info.senders.size());
3227 EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms);
3228 EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
3229}
3230
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003231TEST_F(WebRtcVideoChannel2Test, TranslatesSenderBitrateStatsCorrectly) {
3232 FakeVideoSendStream* stream = AddSendStream();
3233 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003234 stats.target_media_bitrate_bps = 156;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003235 stats.media_bitrate_bps = 123;
3236 stats.substreams[17].total_bitrate_bps = 1;
3237 stats.substreams[17].retransmit_bitrate_bps = 2;
3238 stats.substreams[42].total_bitrate_bps = 3;
3239 stats.substreams[42].retransmit_bitrate_bps = 4;
3240 stream->SetStats(stats);
3241
3242 FakeVideoSendStream* stream2 = AddSendStream();
3243 webrtc::VideoSendStream::Stats stats2;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003244 stats2.target_media_bitrate_bps = 200;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003245 stats2.media_bitrate_bps = 321;
3246 stats2.substreams[13].total_bitrate_bps = 5;
3247 stats2.substreams[13].retransmit_bitrate_bps = 6;
3248 stats2.substreams[21].total_bitrate_bps = 7;
3249 stats2.substreams[21].retransmit_bitrate_bps = 8;
3250 stream2->SetStats(stats2);
3251
3252 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003253 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003254 ASSERT_EQ(2u, info.senders.size());
3255 // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
3256 // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
3257 EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate);
3258 EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate);
pbos@webrtc.org891d4832015-02-26 13:15:22 +00003259 EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
3260 info.bw_estimations[0].target_enc_bitrate);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003261 EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
3262 info.bw_estimations[0].actual_enc_bitrate);
3263 EXPECT_EQ(1 + 3 + 5 + 7, info.bw_estimations[0].transmit_bitrate)
3264 << "Bandwidth stats should take all streams into account.";
3265 EXPECT_EQ(2 + 4 + 6 + 8, info.bw_estimations[0].retransmit_bitrate)
3266 << "Bandwidth stats should take all streams into account.";
3267}
3268
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003269TEST_F(WebRtcVideoChannel2Test, DefaultReceiveStreamReconfiguresToUseRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003270 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003271
Peter Boström0c4e06b2015-10-07 12:23:21 +02003272 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3273 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003274
3275 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
3276 const size_t kDataLength = 12;
3277 uint8_t data[kDataLength];
3278 memset(data, 0, sizeof(data));
3279 rtc::SetBE32(&data[8], ssrcs[0]);
jbaucheec21bd2016-03-20 06:15:43 -07003280 rtc::CopyOnWriteBuffer packet(data, kDataLength);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003281 rtc::PacketTime packet_time;
3282 channel_->OnPacketReceived(&packet, packet_time);
3283
3284 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
3285 << "No default receive stream created.";
3286 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
Peter Boströmd8b01092016-05-12 16:44:36 +02003287 EXPECT_TRUE(recv_stream->GetConfig().rtp.rtx.empty())
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003288 << "Default receive stream should not have configured RTX";
3289
3290 EXPECT_TRUE(channel_->AddRecvStream(
3291 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
3292 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
3293 << "AddRecvStream should've reconfigured, not added a new receiver.";
3294 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
Peter Boströmd8b01092016-05-12 16:44:36 +02003295 EXPECT_FALSE(recv_stream->GetConfig().rtp.rtx.empty());
3296 EXPECT_EQ(recv_stream->GetConfig().decoders.size(),
3297 recv_stream->GetConfig().rtp.rtx.size())
3298 << "RTX should be mapped for all decoders/payload types.";
3299 for (const auto& kv : recv_stream->GetConfig().rtp.rtx) {
3300 EXPECT_EQ(rtx_ssrcs[0], kv.second.ssrc);
3301 }
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00003302}
3303
Peter Boströmd4362cd2015-03-25 14:17:23 +01003304TEST_F(WebRtcVideoChannel2Test, RejectsAddingStreamsWithMissingSsrcsForRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003305 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd4362cd2015-03-25 14:17:23 +01003306
Peter Boström0c4e06b2015-10-07 12:23:21 +02003307 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3308 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd4362cd2015-03-25 14:17:23 +01003309
3310 StreamParams sp =
3311 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
3312 sp.ssrcs = ssrcs; // Without RTXs, this is the important part.
3313
3314 EXPECT_FALSE(channel_->AddSendStream(sp));
3315 EXPECT_FALSE(channel_->AddRecvStream(sp));
3316}
3317
Peter Boströmd6f4c252015-03-26 16:23:04 +01003318TEST_F(WebRtcVideoChannel2Test, RejectsAddingStreamsWithOverlappingRtxSsrcs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003319 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003320
Peter Boström0c4e06b2015-10-07 12:23:21 +02003321 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3322 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd6f4c252015-03-26 16:23:04 +01003323
3324 StreamParams sp =
3325 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
3326
3327 EXPECT_TRUE(channel_->AddSendStream(sp));
3328 EXPECT_TRUE(channel_->AddRecvStream(sp));
3329
3330 // The RTX SSRC is already used in previous streams, using it should fail.
3331 sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]);
3332 EXPECT_FALSE(channel_->AddSendStream(sp));
3333 EXPECT_FALSE(channel_->AddRecvStream(sp));
3334
3335 // After removing the original stream this should be fine to add (makes sure
3336 // that RTX ssrcs are not forever taken).
3337 EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0]));
3338 EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0]));
3339 EXPECT_TRUE(channel_->AddSendStream(sp));
3340 EXPECT_TRUE(channel_->AddRecvStream(sp));
3341}
3342
3343TEST_F(WebRtcVideoChannel2Test,
3344 RejectsAddingStreamsWithOverlappingSimulcastSsrcs) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02003345 static const uint32_t kFirstStreamSsrcs[] = {1, 2, 3};
3346 static const uint32_t kOverlappingStreamSsrcs[] = {4, 3, 5};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003347 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003348
Peter Boströmd6f4c252015-03-26 16:23:04 +01003349 StreamParams sp =
3350 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs));
3351
3352 EXPECT_TRUE(channel_->AddSendStream(sp));
3353 EXPECT_TRUE(channel_->AddRecvStream(sp));
3354
3355 // One of the SSRCs is already used in previous streams, using it should fail.
3356 sp = cricket::CreateSimStreamParams("cname",
3357 MAKE_VECTOR(kOverlappingStreamSsrcs));
3358 EXPECT_FALSE(channel_->AddSendStream(sp));
3359 EXPECT_FALSE(channel_->AddRecvStream(sp));
3360
3361 // After removing the original stream this should be fine to add (makes sure
3362 // that RTX ssrcs are not forever taken).
Peter Boström3548dd22015-05-22 18:48:36 +02003363 EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0]));
3364 EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0]));
Peter Boströmd6f4c252015-03-26 16:23:04 +01003365 EXPECT_TRUE(channel_->AddSendStream(sp));
3366 EXPECT_TRUE(channel_->AddRecvStream(sp));
3367}
3368
Peter Boström259bd202015-05-28 13:39:50 +02003369TEST_F(WebRtcVideoChannel2Test, ReportsSsrcGroupsInStats) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003370 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström259bd202015-05-28 13:39:50 +02003371
3372 static const uint32_t kSenderSsrcs[] = {4, 7, 10};
3373 static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11};
3374
3375 StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams(
3376 "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs));
3377
3378 EXPECT_TRUE(channel_->AddSendStream(sender_sp));
3379
3380 static const uint32_t kReceiverSsrcs[] = {3};
3381 static const uint32_t kReceiverRtxSsrcs[] = {2};
3382
3383 StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams(
3384 "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs));
3385 EXPECT_TRUE(channel_->AddRecvStream(receiver_sp));
3386
3387 cricket::VideoMediaInfo info;
3388 ASSERT_TRUE(channel_->GetStats(&info));
3389
3390 ASSERT_EQ(1u, info.senders.size());
3391 ASSERT_EQ(1u, info.receivers.size());
3392
3393 EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups);
3394 EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups);
3395 EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
3396}
3397
pbosf42376c2015-08-28 07:35:32 -07003398TEST_F(WebRtcVideoChannel2Test, MapsReceivedPayloadTypeToCodecName) {
3399 FakeVideoReceiveStream* stream = AddRecvStream();
3400 webrtc::VideoReceiveStream::Stats stats;
3401 cricket::VideoMediaInfo info;
3402
3403 // Report no codec name before receiving.
3404 stream->SetStats(stats);
3405 ASSERT_TRUE(channel_->GetStats(&info));
3406 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
3407
3408 // Report VP8 if we're receiving it.
3409 stats.current_payload_type = kDefaultVp8PlType;
3410 stream->SetStats(stats);
3411 ASSERT_TRUE(channel_->GetStats(&info));
3412 EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());
3413
3414 // Report no codec name for unknown playload types.
3415 stats.current_payload_type = 3;
3416 stream->SetStats(stats);
3417 ASSERT_TRUE(channel_->GetStats(&info));
3418 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
3419}
3420
noahricd10a68e2015-07-10 11:27:55 -07003421void WebRtcVideoChannel2Test::TestReceiveUnsignalledSsrcPacket(
3422 uint8_t payload_type,
3423 bool expect_created_receive_stream) {
noahricd10a68e2015-07-10 11:27:55 -07003424 // Add a RED RTX codec.
3425 VideoCodec red_rtx_codec =
3426 VideoCodec::CreateRtxCodec(kRedRtxPayloadType, kDefaultRedPlType);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003427 recv_parameters_.codecs.push_back(red_rtx_codec);
3428 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
noahricd10a68e2015-07-10 11:27:55 -07003429
3430 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
3431 const size_t kDataLength = 12;
3432 uint8_t data[kDataLength];
3433 memset(data, 0, sizeof(data));
3434
3435 rtc::Set8(data, 1, payload_type);
3436 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
jbaucheec21bd2016-03-20 06:15:43 -07003437 rtc::CopyOnWriteBuffer packet(data, kDataLength);
noahricd10a68e2015-07-10 11:27:55 -07003438 rtc::PacketTime packet_time;
3439 channel_->OnPacketReceived(&packet, packet_time);
3440
3441 if (expect_created_receive_stream) {
3442 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
3443 << "Should have created a receive stream for payload type: "
3444 << payload_type;
3445 } else {
3446 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size())
3447 << "Shouldn't have created a receive stream for payload type: "
3448 << payload_type;
3449 }
3450}
3451
3452TEST_F(WebRtcVideoChannel2Test, Vp8PacketCreatesUnsignalledStream) {
3453 TestReceiveUnsignalledSsrcPacket(kDefaultVp8PlType, true);
3454}
3455
3456TEST_F(WebRtcVideoChannel2Test, Vp9PacketCreatesUnsignalledStream) {
3457 TestReceiveUnsignalledSsrcPacket(kDefaultVp9PlType, true);
3458}
3459
3460TEST_F(WebRtcVideoChannel2Test, RtxPacketDoesntCreateUnsignalledStream) {
3461 TestReceiveUnsignalledSsrcPacket(kDefaultRtxVp8PlType, false);
3462}
3463
3464TEST_F(WebRtcVideoChannel2Test, UlpfecPacketDoesntCreateUnsignalledStream) {
3465 TestReceiveUnsignalledSsrcPacket(kDefaultUlpfecType, false);
3466}
3467
3468TEST_F(WebRtcVideoChannel2Test, RedRtxPacketDoesntCreateUnsignalledStream) {
3469 TestReceiveUnsignalledSsrcPacket(kRedRtxPayloadType, false);
3470}
3471
skvladdc1c62c2016-03-16 19:07:43 -07003472TEST_F(WebRtcVideoChannel2Test, CanSentMaxBitrateForExistingStream) {
3473 AddSendStream();
3474
3475 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07003476 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, &capturer));
skvladdc1c62c2016-03-16 19:07:43 -07003477 cricket::VideoFormat capture_format_hd =
3478 capturer.GetSupportedFormats()->front();
3479 EXPECT_EQ(1280, capture_format_hd.width);
3480 EXPECT_EQ(720, capture_format_hd.height);
3481 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
3482 EXPECT_TRUE(channel_->SetSend(true));
3483
3484 int default_encoder_bitrate = GetMaxEncoderBitrate(capturer);
3485 EXPECT_TRUE(default_encoder_bitrate > 1000);
3486
3487 // TODO(skvlad): Resolve the inconsistency between the interpretation
3488 // of the global bitrate limit for audio and video:
3489 // - Audio: max_bandwidth_bps = 0 - fail the operation,
3490 // max_bandwidth_bps = -1 - remove the bandwidth limit
3491 // - Video: max_bandwidth_bps = 0 - remove the bandwidth limit,
3492 // max_bandwidth_bps = -1 - do not change the previously set
3493 // limit.
3494
3495 SetAndExpectMaxBitrate(capturer, 1000, 0, 1000);
3496 SetAndExpectMaxBitrate(capturer, 1000, 800, 800);
3497 SetAndExpectMaxBitrate(capturer, 600, 800, 600);
3498 SetAndExpectMaxBitrate(capturer, 0, 800, 800);
3499 SetAndExpectMaxBitrate(capturer, 0, 0, default_encoder_bitrate);
3500
deadbeef5a4a75a2016-06-02 16:23:38 -07003501 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, nullptr, nullptr));
skvladdc1c62c2016-03-16 19:07:43 -07003502}
3503
3504TEST_F(WebRtcVideoChannel2Test, CannotSetMaxBitrateForNonexistentStream) {
3505 webrtc::RtpParameters nonexistent_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003506 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07003507 EXPECT_EQ(0, nonexistent_parameters.encodings.size());
3508
3509 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003510 EXPECT_FALSE(
3511 channel_->SetRtpSendParameters(last_ssrc_, nonexistent_parameters));
skvladdc1c62c2016-03-16 19:07:43 -07003512}
3513
3514TEST_F(WebRtcVideoChannel2Test,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003515 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvladdc1c62c2016-03-16 19:07:43 -07003516 // This test verifies that setting RtpParameters succeeds only if
3517 // the structure contains exactly one encoding.
deadbeefdbe2b872016-03-22 15:42:00 -07003518 // TODO(skvlad): Update this test when we start supporting setting parameters
skvladdc1c62c2016-03-16 19:07:43 -07003519 // for each encoding individually.
3520
3521 AddSendStream();
3522 // Setting RtpParameters with no encoding is expected to fail.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003523 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
3524 parameters.encodings.clear();
3525 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07003526 // Setting RtpParameters with exactly one encoding should succeed.
3527 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003528 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07003529 // Two or more encodings should result in failure.
3530 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003531 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
skvladdc1c62c2016-03-16 19:07:43 -07003532}
3533
deadbeefdbe2b872016-03-22 15:42:00 -07003534// Test that a stream will not be sending if its encoding is made
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003535// inactive through SetRtpSendParameters.
deadbeefdbe2b872016-03-22 15:42:00 -07003536// TODO(deadbeef): Update this test when we start supporting setting parameters
3537// for each encoding individually.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003538TEST_F(WebRtcVideoChannel2Test, SetRtpSendParametersEncodingsActive) {
deadbeefdbe2b872016-03-22 15:42:00 -07003539 FakeVideoSendStream* stream = AddSendStream();
3540 EXPECT_TRUE(channel_->SetSend(true));
3541 EXPECT_TRUE(stream->IsSending());
3542
3543 // Get current parameters and change "active" to false.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003544 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
deadbeefdbe2b872016-03-22 15:42:00 -07003545 ASSERT_EQ(1u, parameters.encodings.size());
3546 ASSERT_TRUE(parameters.encodings[0].active);
3547 parameters.encodings[0].active = false;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003548 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
deadbeefdbe2b872016-03-22 15:42:00 -07003549 EXPECT_FALSE(stream->IsSending());
3550
3551 // Now change it back to active and verify we resume sending.
3552 parameters.encodings[0].active = true;
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003553 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters));
deadbeefdbe2b872016-03-22 15:42:00 -07003554 EXPECT_TRUE(stream->IsSending());
3555}
3556
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003557// Test that GetRtpSendParameters returns the currently configured codecs.
3558TEST_F(WebRtcVideoChannel2Test, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003559 AddSendStream();
3560 cricket::VideoSendParameters parameters;
3561 parameters.codecs.push_back(kVp8Codec);
3562 parameters.codecs.push_back(kVp9Codec);
3563 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3564
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003565 webrtc::RtpParameters rtp_parameters =
3566 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003567 ASSERT_EQ(2u, rtp_parameters.codecs.size());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003568 EXPECT_EQ(kVp8Codec.ToCodecParameters(), rtp_parameters.codecs[0]);
3569 EXPECT_EQ(kVp9Codec.ToCodecParameters(), rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003570}
3571
3572// Test that if we set/get parameters multiple times, we get the same results.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003573TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003574 AddSendStream();
3575 cricket::VideoSendParameters parameters;
3576 parameters.codecs.push_back(kVp8Codec);
3577 parameters.codecs.push_back(kVp9Codec);
3578 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3579
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003580 webrtc::RtpParameters initial_params =
3581 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003582
3583 // We should be able to set the params we just got.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003584 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, initial_params));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003585
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003586 // ... And this shouldn't change the params returned by GetRtpSendParameters.
3587 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(last_ssrc_));
3588}
3589
3590// Test that GetRtpReceiveParameters returns the currently configured codecs.
3591TEST_F(WebRtcVideoChannel2Test, GetRtpReceiveParametersCodecs) {
3592 AddRecvStream();
3593 cricket::VideoRecvParameters parameters;
3594 parameters.codecs.push_back(kVp8Codec);
3595 parameters.codecs.push_back(kVp9Codec);
3596 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
3597
3598 webrtc::RtpParameters rtp_parameters =
3599 channel_->GetRtpReceiveParameters(last_ssrc_);
3600 ASSERT_EQ(2u, rtp_parameters.codecs.size());
3601 EXPECT_EQ(kVp8Codec.ToCodecParameters(), rtp_parameters.codecs[0]);
3602 EXPECT_EQ(kVp9Codec.ToCodecParameters(), rtp_parameters.codecs[1]);
3603}
3604
johan073ece42016-08-26 02:59:47 -07003605#if defined(WEBRTC_USE_H264)
johan3859c892016-08-05 09:19:25 -07003606TEST_F(WebRtcVideoChannel2Test, GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07003607#else
3608TEST_F(WebRtcVideoChannel2Test, DISABLED_GetRtpReceiveFmtpSprop) {
3609#endif
johan3859c892016-08-05 09:19:25 -07003610 cricket::VideoRecvParameters parameters;
3611 cricket::VideoCodec kH264sprop1(101, "H264", 640, 400, 15);
3612 kH264sprop1.SetParam("sprop-parameter-sets", "uvw");
3613 parameters.codecs.push_back(kH264sprop1);
3614 cricket::VideoCodec kH264sprop2(102, "H264", 640, 400, 15);
3615 kH264sprop2.SetParam("sprop-parameter-sets", "xyz");
3616 parameters.codecs.push_back(kH264sprop2);
3617 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
3618
3619 FakeVideoReceiveStream* recv_stream = AddRecvStream();
3620 const webrtc::VideoReceiveStream::Config& cfg = recv_stream->GetConfig();
3621 webrtc::RtpParameters rtp_parameters =
3622 channel_->GetRtpReceiveParameters(last_ssrc_);
3623 ASSERT_EQ(2u, rtp_parameters.codecs.size());
3624 EXPECT_EQ(kH264sprop1.ToCodecParameters(), rtp_parameters.codecs[0]);
3625 ASSERT_EQ(2u, cfg.decoders.size());
3626 EXPECT_EQ(101, cfg.decoders[0].payload_type);
3627 EXPECT_EQ("H264", cfg.decoders[0].payload_name);
3628 std::string sprop;
3629 const webrtc::DecoderSpecificSettings* decoder_specific;
3630 decoder_specific = &cfg.decoders[0].decoder_specific;
3631 ASSERT_TRUE(static_cast<bool>(decoder_specific->h264_extra_settings));
3632 sprop = decoder_specific->h264_extra_settings->sprop_parameter_sets;
3633 EXPECT_EQ("uvw", sprop);
3634
3635 EXPECT_EQ(102, cfg.decoders[1].payload_type);
3636 EXPECT_EQ("H264", cfg.decoders[1].payload_name);
3637 decoder_specific = &cfg.decoders[1].decoder_specific;
3638 ASSERT_TRUE(static_cast<bool>(decoder_specific->h264_extra_settings));
3639 sprop = decoder_specific->h264_extra_settings->sprop_parameter_sets;
3640 EXPECT_EQ("xyz", sprop);
3641}
3642
sakal1fd95952016-06-22 00:46:15 -07003643// Test that RtpParameters for receive stream has one encoding and it has
3644// the correct SSRC.
3645TEST_F(WebRtcVideoChannel2Test, RtpEncodingParametersSsrcIsSet) {
3646 AddRecvStream();
3647
3648 webrtc::RtpParameters rtp_parameters =
3649 channel_->GetRtpReceiveParameters(last_ssrc_);
3650 ASSERT_EQ(1u, rtp_parameters.encodings.size());
3651 EXPECT_EQ(rtc::Optional<uint32_t>(last_ssrc_),
3652 rtp_parameters.encodings[0].ssrc);
3653}
3654
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07003655// Test that if we set/get parameters multiple times, we get the same results.
3656TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpReceiveParameters) {
3657 AddRecvStream();
3658 cricket::VideoRecvParameters parameters;
3659 parameters.codecs.push_back(kVp8Codec);
3660 parameters.codecs.push_back(kVp9Codec);
3661 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
3662
3663 webrtc::RtpParameters initial_params =
3664 channel_->GetRtpReceiveParameters(last_ssrc_);
3665
3666 // We should be able to set the params we just got.
3667 EXPECT_TRUE(channel_->SetRtpReceiveParameters(last_ssrc_, initial_params));
3668
3669 // ... And this shouldn't change the params returned by
3670 // GetRtpReceiveParameters.
3671 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(last_ssrc_));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07003672}
3673
Peter Boström3548dd22015-05-22 18:48:36 +02003674void WebRtcVideoChannel2Test::TestReceiverLocalSsrcConfiguration(
3675 bool receiver_first) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003676 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström3548dd22015-05-22 18:48:36 +02003677
3678 const uint32_t kSenderSsrc = 0xC0FFEE;
Peter Boströmdfa28152015-10-21 17:21:10 +02003679 const uint32_t kSecondSenderSsrc = 0xBADCAFE;
Peter Boström3548dd22015-05-22 18:48:36 +02003680 const uint32_t kReceiverSsrc = 0x4711;
Peter Boströmdfa28152015-10-21 17:21:10 +02003681 const uint32_t kExpectedDefaultReceiverSsrc = 1;
Peter Boström3548dd22015-05-22 18:48:36 +02003682
3683 if (receiver_first) {
3684 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
3685 std::vector<FakeVideoReceiveStream*> receive_streams =
3686 fake_call_->GetVideoReceiveStreams();
3687 ASSERT_EQ(1u, receive_streams.size());
Peter Boströmdfa28152015-10-21 17:21:10 +02003688 // Default local SSRC when we have no sender.
3689 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
3690 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02003691 }
3692 AddSendStream(StreamParams::CreateLegacy(kSenderSsrc));
3693 if (!receiver_first)
3694 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
3695 std::vector<FakeVideoReceiveStream*> receive_streams =
3696 fake_call_->GetVideoReceiveStreams();
3697 ASSERT_EQ(1u, receive_streams.size());
3698 EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boströmdfa28152015-10-21 17:21:10 +02003699
3700 // Removing first sender should fall back to another (in this case the second)
3701 // local send stream's SSRC.
3702 AddSendStream(StreamParams::CreateLegacy(kSecondSenderSsrc));
3703 ASSERT_TRUE(channel_->RemoveSendStream(kSenderSsrc));
3704 receive_streams =
3705 fake_call_->GetVideoReceiveStreams();
3706 ASSERT_EQ(1u, receive_streams.size());
3707 EXPECT_EQ(kSecondSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
3708
3709 // Removing the last sender should fall back to default local SSRC.
3710 ASSERT_TRUE(channel_->RemoveSendStream(kSecondSenderSsrc));
3711 receive_streams =
3712 fake_call_->GetVideoReceiveStreams();
3713 ASSERT_EQ(1u, receive_streams.size());
3714 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
3715 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02003716}
3717
3718TEST_F(WebRtcVideoChannel2Test, ConfiguresLocalSsrc) {
3719 TestReceiverLocalSsrcConfiguration(false);
3720}
3721
3722TEST_F(WebRtcVideoChannel2Test, ConfiguresLocalSsrcOnExistingReceivers) {
3723 TestReceiverLocalSsrcConfiguration(true);
3724}
3725
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003726class WebRtcVideoChannel2SimulcastTest : public testing::Test {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003727 public:
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003728 WebRtcVideoChannel2SimulcastTest() : fake_call_(webrtc::Call::Config()) {}
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003729
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003730 void SetUp() override {
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +02003731 engine_.Init();
nisse51542be2016-02-12 02:27:06 -08003732 channel_.reset(
3733 engine_.CreateChannel(&fake_call_, MediaConfig(), VideoOptions()));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003734 last_ssrc_ = 123;
3735 }
3736
3737 protected:
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003738 void VerifySimulcastSettings(const VideoCodec& codec,
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003739 size_t num_configured_streams,
pbosbe16f792015-10-16 12:49:39 -07003740 size_t expected_num_streams) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003741 cricket::VideoSendParameters parameters;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003742 parameters.codecs.push_back(codec);
3743 ASSERT_TRUE(channel_->SetSendParameters(parameters));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003744
Peter Boström0c4e06b2015-10-07 12:23:21 +02003745 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
henrikg91d6ede2015-09-17 00:24:34 -07003746 RTC_DCHECK(num_configured_streams <= ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003747 ssrcs.resize(num_configured_streams);
3748
3749 FakeVideoSendStream* stream =
3750 AddSendStream(CreateSimStreamParams("cname", ssrcs));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003751 // Send a full-size frame to trigger a stream reconfiguration to use all
3752 // expected simulcast layers.
3753 cricket::FakeVideoCapturer capturer;
deadbeef5a4a75a2016-06-02 16:23:38 -07003754 EXPECT_TRUE(
3755 channel_->SetVideoSend(ssrcs.front(), true, nullptr, &capturer));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003756 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(cricket::VideoFormat(
3757 codec.width, codec.height,
3758 cricket::VideoFormat::FpsToInterval(30),
3759 cricket::FOURCC_I420)));
3760 channel_->SetSend(true);
3761 EXPECT_TRUE(capturer.CaptureFrame());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003762
3763 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
3764 ASSERT_EQ(expected_num_streams, video_streams.size());
3765
3766 std::vector<webrtc::VideoStream> expected_streams = GetSimulcastConfig(
pbosbe16f792015-10-16 12:49:39 -07003767 num_configured_streams, codec.width, codec.height, 0, kDefaultQpMax,
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003768 codec.framerate != 0 ? codec.framerate : kDefaultFramerate);
3769
3770 ASSERT_EQ(expected_streams.size(), video_streams.size());
3771
3772 size_t num_streams = video_streams.size();
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003773 int total_max_bitrate_bps = 0;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003774 for (size_t i = 0; i < num_streams; ++i) {
3775 EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
3776 EXPECT_EQ(expected_streams[i].height, video_streams[i].height);
3777
3778 EXPECT_GT(video_streams[i].max_framerate, 0);
3779 EXPECT_EQ(expected_streams[i].max_framerate,
3780 video_streams[i].max_framerate);
3781
3782 EXPECT_GT(video_streams[i].min_bitrate_bps, 0);
3783 EXPECT_EQ(expected_streams[i].min_bitrate_bps,
3784 video_streams[i].min_bitrate_bps);
3785
3786 EXPECT_GT(video_streams[i].target_bitrate_bps, 0);
3787 EXPECT_EQ(expected_streams[i].target_bitrate_bps,
3788 video_streams[i].target_bitrate_bps);
3789
3790 EXPECT_GT(video_streams[i].max_bitrate_bps, 0);
3791 EXPECT_EQ(expected_streams[i].max_bitrate_bps,
3792 video_streams[i].max_bitrate_bps);
3793
3794 EXPECT_GT(video_streams[i].max_qp, 0);
3795 EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp);
3796
3797 EXPECT_FALSE(expected_streams[i].temporal_layer_thresholds_bps.empty());
3798 EXPECT_EQ(expected_streams[i].temporal_layer_thresholds_bps,
3799 video_streams[i].temporal_layer_thresholds_bps);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003800
3801 if (i == num_streams - 1) {
3802 total_max_bitrate_bps += video_streams[i].max_bitrate_bps;
3803 } else {
3804 total_max_bitrate_bps += video_streams[i].target_bitrate_bps;
3805 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003806 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003807 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003808 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003809 ASSERT_EQ(1u, info.senders.size());
3810 EXPECT_EQ(total_max_bitrate_bps, info.senders[0].preferred_bitrate);
3811
deadbeef5a4a75a2016-06-02 16:23:38 -07003812 EXPECT_TRUE(channel_->SetVideoSend(ssrcs.front(), true, nullptr, nullptr));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003813 }
3814
3815 FakeVideoSendStream* AddSendStream() {
3816 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++));
3817 }
3818
3819 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
3820 size_t num_streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003821 fake_call_.GetVideoSendStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003822 EXPECT_TRUE(channel_->AddSendStream(sp));
3823 std::vector<FakeVideoSendStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003824 fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003825 EXPECT_EQ(num_streams + 1, streams.size());
3826 return streams[streams.size() - 1];
3827 }
3828
3829 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003830 return fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003831 }
3832
3833 FakeVideoReceiveStream* AddRecvStream() {
3834 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++));
3835 }
3836
3837 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
3838 size_t num_streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003839 fake_call_.GetVideoReceiveStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003840 EXPECT_TRUE(channel_->AddRecvStream(sp));
3841 std::vector<FakeVideoReceiveStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003842 fake_call_.GetVideoReceiveStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003843 EXPECT_EQ(num_streams + 1, streams.size());
3844 return streams[streams.size() - 1];
3845 }
3846
Fredrik Solenberg709ed672015-09-15 12:26:33 +02003847 FakeCall fake_call_;
3848 WebRtcVideoEngine2 engine_;
kwiberg686a8ef2016-02-26 03:00:35 -08003849 std::unique_ptr<VideoMediaChannel> channel_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02003850 uint32_t last_ssrc_;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003851};
3852
3853TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith2SimulcastStreams) {
pbosbe16f792015-10-16 12:49:39 -07003854 VerifySimulcastSettings(kVp8Codec, 2, 2);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003855}
3856
3857TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith3SimulcastStreams) {
pbosbe16f792015-10-16 12:49:39 -07003858 VerifySimulcastSettings(kVp8Codec720p, 3, 3);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003859}
3860
3861// Test that we normalize send codec format size in simulcast.
3862TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
3863 cricket::VideoCodec codec(kVp8Codec270p);
3864 codec.width += 1;
3865 codec.height += 1;
pbosbe16f792015-10-16 12:49:39 -07003866 VerifySimulcastSettings(codec, 2, 2);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003867}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003868} // namespace cricket