blob: 52acec40826a50e19fe3ed535f9ff530a4cd678f [file] [log] [blame]
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001/*
2 * libjingle
3 * Copyright 2004 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +000028#include <algorithm>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000029#include <map>
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000030#include <vector>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000031
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000032#include "talk/media/base/testutils.h"
33#include "talk/media/base/videoengine_unittest.h"
Fredrik Solenbergb6728822015-04-22 15:35:17 +020034#include "talk/media/webrtc/fakewebrtccall.h"
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +000035#include "talk/media/webrtc/fakewebrtcvideoengine.h"
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000036#include "talk/media/webrtc/simulcast.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000037#include "talk/media/webrtc/webrtcvideochannelfactory.h"
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000038#include "talk/media/webrtc/webrtcvideoengine2.h"
pbos@webrtc.org3bf3d232014-10-31 12:59:34 +000039#include "talk/media/webrtc/webrtcvoiceengine.h"
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +000040#include "webrtc/base/arraysize.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000041#include "webrtc/base/gunit.h"
42#include "webrtc/base/stringutils.h"
pbos@webrtc.org42684be2014-10-03 11:25:45 +000043#include "webrtc/video_encoder.h"
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000044
45namespace {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000046static const int kDefaultQpMax = 56;
47static const int kDefaultFramerate = 30;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000048
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000049static const cricket::VideoCodec kVp8Codec720p(100, "VP8", 1280, 720, 30, 0);
50static const cricket::VideoCodec kVp8Codec360p(100, "VP8", 640, 360, 30, 0);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000051static const cricket::VideoCodec kVp8Codec270p(100, "VP8", 480, 270, 30, 0);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000052
53static const cricket::VideoCodec kVp8Codec(100, "VP8", 640, 400, 30, 0);
54static const cricket::VideoCodec kVp9Codec(101, "VP9", 640, 400, 30, 0);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +000055static const cricket::VideoCodec kH264Codec(102, "H264", 640, 400, 30, 0);
56
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000057static const cricket::VideoCodec kRedCodec(116, "red", 0, 0, 0, 0);
58static const cricket::VideoCodec kUlpfecCodec(117, "ulpfec", 0, 0, 0, 0);
59
noahricd10a68e2015-07-10 11:27:55 -070060static const uint8_t kRedRtxPayloadType = 125;
61
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000062static const uint32 kSsrcs1[] = {1};
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000063static const uint32 kSsrcs3[] = {1, 2, 3};
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000064static const uint32 kRtxSsrcs1[] = {4};
noahricd10a68e2015-07-10 11:27:55 -070065static const uint32 kIncomingUnsignalledSsrc = 0xC0FFEE;
pbos@webrtc.org3c107582014-07-20 15:27:35 +000066static const char kUnsupportedExtensionName[] =
67 "urn:ietf:params:rtp-hdrext:unsupported";
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000068
69void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) {
70 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
71 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
72 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
73 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
74 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
75 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
76 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
77 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
78}
79
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -070080static void CreateBlackFrame(webrtc::VideoFrame* video_frame,
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +000081 int width,
82 int height) {
83 video_frame->CreateEmptyFrame(
84 width, height, width, (width + 1) / 2, (width + 1) / 2);
85 memset(video_frame->buffer(webrtc::kYPlane), 16,
86 video_frame->allocated_size(webrtc::kYPlane));
87 memset(video_frame->buffer(webrtc::kUPlane), 128,
88 video_frame->allocated_size(webrtc::kUPlane));
89 memset(video_frame->buffer(webrtc::kVPlane), 128,
90 video_frame->allocated_size(webrtc::kVPlane));
91}
92
Shao Changbine62202f2015-04-21 20:24:50 +080093void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config,
94 const std::map<int, int>& rtx_types) {
95 std::map<int, int>::const_iterator it;
96 it = rtx_types.find(config.encoder_settings.payload_type);
97 EXPECT_TRUE(it != rtx_types.end() &&
98 it->second == config.rtp.rtx.payload_type);
99
100 if (config.rtp.fec.red_rtx_payload_type != -1) {
101 it = rtx_types.find(config.rtp.fec.red_payload_type);
102 EXPECT_TRUE(it != rtx_types.end() &&
103 it->second == config.rtp.fec.red_rtx_payload_type);
104 }
105}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000106} // namespace
107
108namespace cricket {
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000109class WebRtcVideoEngine2Test : public ::testing::Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000110 public:
pbos@webrtc.orgf1f0d9a2015-03-02 13:30:15 +0000111 WebRtcVideoEngine2Test() : WebRtcVideoEngine2Test(nullptr) {}
112 WebRtcVideoEngine2Test(WebRtcVoiceEngine* voice_engine)
113 : engine_(voice_engine) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000114 std::vector<VideoCodec> engine_codecs = engine_.codecs();
Fredrik Solenbergd3ddc1b2015-05-07 17:07:34 +0200115 DCHECK(!engine_codecs.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000116 bool codec_set = false;
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000117 for (size_t i = 0; i < engine_codecs.size(); ++i) {
118 if (engine_codecs[i].name == "red") {
119 default_red_codec_ = engine_codecs[i];
120 } else if (engine_codecs[i].name == "ulpfec") {
121 default_ulpfec_codec_ = engine_codecs[i];
122 } else if (engine_codecs[i].name == "rtx") {
Shao Changbine62202f2015-04-21 20:24:50 +0800123 int associated_payload_type;
124 if (engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
125 &associated_payload_type)) {
126 default_apt_rtx_types_[associated_payload_type] = engine_codecs[i].id;
127 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000128 } else if (!codec_set) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000129 default_codec_ = engine_codecs[i];
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000130 codec_set = true;
131 }
132 }
133
Fredrik Solenbergd3ddc1b2015-05-07 17:07:34 +0200134 DCHECK(codec_set);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000135 }
136
137 protected:
pbos@webrtc.org3bf3d232014-10-31 12:59:34 +0000138 class FakeCallFactory : public WebRtcCallFactory {
139 public:
140 FakeCallFactory() : fake_call_(NULL) {}
141 FakeCall* GetCall() { return fake_call_; }
142
143 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000144 webrtc::Call* CreateCall(const webrtc::Call::Config& config) override {
Fredrik Solenbergd3ddc1b2015-05-07 17:07:34 +0200145 DCHECK(fake_call_ == NULL);
pbos@webrtc.org3bf3d232014-10-31 12:59:34 +0000146 fake_call_ = new FakeCall(config);
147 return fake_call_;
148 }
149
150 FakeCall* fake_call_;
151 };
152
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000153 VideoMediaChannel* SetUpForExternalEncoderFactory(
154 cricket::WebRtcVideoEncoderFactory* encoder_factory,
155 const std::vector<VideoCodec>& codecs);
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000156
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000157 VideoMediaChannel* SetUpForExternalDecoderFactory(
158 cricket::WebRtcVideoDecoderFactory* decoder_factory,
159 const std::vector<VideoCodec>& codecs);
160
pbos@webrtc.orgf1f0d9a2015-03-02 13:30:15 +0000161 // Used in WebRtcVideoEngine2VoiceTest, but defined here so it's properly
162 // initialized when the constructor is called.
163 WebRtcVoiceEngine voice_engine_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000164 WebRtcVideoEngine2 engine_;
165 VideoCodec default_codec_;
166 VideoCodec default_red_codec_;
167 VideoCodec default_ulpfec_codec_;
Shao Changbine62202f2015-04-21 20:24:50 +0800168 std::map<int, int> default_apt_rtx_types_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000169};
170
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000171TEST_F(WebRtcVideoEngine2Test, FindCodec) {
172 const std::vector<cricket::VideoCodec>& c = engine_.codecs();
Shao Changbine62202f2015-04-21 20:24:50 +0800173 EXPECT_EQ(cricket::DefaultVideoCodecList().size(), c.size());
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000174
175 cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0);
176 EXPECT_TRUE(engine_.FindCodec(vp8));
177
178 cricket::VideoCodec vp8_ci(104, "vp8", 320, 200, 30, 0);
179 EXPECT_TRUE(engine_.FindCodec(vp8));
180
181 cricket::VideoCodec vp8_diff_fr_diff_pref(104, "VP8", 320, 200, 50, 50);
182 EXPECT_TRUE(engine_.FindCodec(vp8_diff_fr_diff_pref));
183
184 cricket::VideoCodec vp8_diff_id(95, "VP8", 320, 200, 30, 0);
185 EXPECT_FALSE(engine_.FindCodec(vp8_diff_id));
186 vp8_diff_id.id = 97;
187 EXPECT_TRUE(engine_.FindCodec(vp8_diff_id));
188
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000189 // FindCodec ignores the codec size.
190 // Test that FindCodec can accept uncommon codec size.
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000191 cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0);
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000192 EXPECT_TRUE(engine_.FindCodec(vp8_diff_res));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000193
194 // PeerConnection doesn't negotiate the resolution at this point.
195 // Test that FindCodec can handle the case when width/height is 0.
196 cricket::VideoCodec vp8_zero_res(104, "VP8", 0, 0, 30, 0);
197 EXPECT_TRUE(engine_.FindCodec(vp8_zero_res));
198
199 cricket::VideoCodec red(101, "RED", 0, 0, 30, 0);
200 EXPECT_TRUE(engine_.FindCodec(red));
201
202 cricket::VideoCodec red_ci(101, "red", 0, 0, 30, 0);
203 EXPECT_TRUE(engine_.FindCodec(red));
204
205 cricket::VideoCodec fec(102, "ULPFEC", 0, 0, 30, 0);
206 EXPECT_TRUE(engine_.FindCodec(fec));
207
208 cricket::VideoCodec fec_ci(102, "ulpfec", 0, 0, 30, 0);
209 EXPECT_TRUE(engine_.FindCodec(fec));
210
211 cricket::VideoCodec rtx(96, "rtx", 0, 0, 30, 0);
212 EXPECT_TRUE(engine_.FindCodec(rtx));
213}
214
pbos@webrtc.org2a72c652015-02-26 16:01:24 +0000215TEST_F(WebRtcVideoEngine2Test, SetDefaultEncoderConfigPreservesFeedbackParams) {
216 cricket::VideoCodec max_settings(
217 engine_.codecs()[0].id, engine_.codecs()[0].name,
218 engine_.codecs()[0].width / 2, engine_.codecs()[0].height / 2, 30, 0);
219 // This codec shouldn't have NACK by default or the test is pointless.
220 EXPECT_FALSE(max_settings.HasFeedbackParam(
221 FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)));
222 // The engine should by default have it however.
223 EXPECT_TRUE(engine_.codecs()[0].HasFeedbackParam(
224 FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)));
225
226 // Set constrained max codec settings.
227 EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
228 cricket::VideoEncoderConfig(max_settings)));
229
230 // Verify that feedback parameters are retained.
231 EXPECT_TRUE(engine_.codecs()[0].HasFeedbackParam(
232 FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)));
233}
234
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000235TEST_F(WebRtcVideoEngine2Test, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
236 std::vector<VideoCodec> engine_codecs = engine_.codecs();
237 for (size_t i = 0; i < engine_codecs.size(); ++i) {
238 if (engine_codecs[i].name != kRtxCodecName)
239 continue;
240 int associated_payload_type;
241 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000242 &associated_payload_type));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000243 EXPECT_EQ(default_codec_.id, associated_payload_type);
244 return;
245 }
246 FAIL() << "No RTX codec found among default codecs.";
247}
248
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000249TEST_F(WebRtcVideoEngine2Test, SupportsTimestampOffsetHeaderExtension) {
250 std::vector<RtpHeaderExtension> extensions = engine_.rtp_header_extensions();
251 ASSERT_FALSE(extensions.empty());
252 for (size_t i = 0; i < extensions.size(); ++i) {
253 if (extensions[i].uri == kRtpTimestampOffsetHeaderExtension) {
254 EXPECT_EQ(kRtpTimestampOffsetHeaderExtensionDefaultId, extensions[i].id);
255 return;
256 }
257 }
258 FAIL() << "Timestamp offset extension not in header-extension list.";
259}
260
261TEST_F(WebRtcVideoEngine2Test, SupportsAbsoluteSenderTimeHeaderExtension) {
262 std::vector<RtpHeaderExtension> extensions = engine_.rtp_header_extensions();
263 ASSERT_FALSE(extensions.empty());
264 for (size_t i = 0; i < extensions.size(); ++i) {
265 if (extensions[i].uri == kRtpAbsoluteSenderTimeHeaderExtension) {
266 EXPECT_EQ(kRtpAbsoluteSenderTimeHeaderExtensionDefaultId,
267 extensions[i].id);
268 return;
269 }
270 }
271 FAIL() << "Absolute Sender Time extension not in header-extension list.";
272}
273
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700274TEST_F(WebRtcVideoEngine2Test, SupportsVideoRotationHeaderExtension) {
275 std::vector<RtpHeaderExtension> extensions = engine_.rtp_header_extensions();
276 ASSERT_FALSE(extensions.empty());
277 for (size_t i = 0; i < extensions.size(); ++i) {
278 if (extensions[i].uri == kRtpVideoRotationHeaderExtension) {
279 EXPECT_EQ(kRtpVideoRotationHeaderExtensionDefaultId, extensions[i].id);
280 return;
281 }
282 }
283 FAIL() << "Video Rotation extension not in header-extension list.";
284}
285
286TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionBeforeCapturer) {
287 // Allocate the capturer first to prevent early destruction before channel's
288 // dtor is called.
289 cricket::FakeVideoCapturer capturer;
290
291 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
292 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
293 std::vector<cricket::VideoCodec> codecs;
294 codecs.push_back(kVp8Codec);
295
296 rtc::scoped_ptr<VideoMediaChannel> channel(
297 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
298 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
299
300 // Add CVO extension.
301 const int id = 1;
302 std::vector<cricket::RtpHeaderExtension> extensions;
303 extensions.push_back(
304 cricket::RtpHeaderExtension(kRtpVideoRotationHeaderExtension, id));
305 EXPECT_TRUE(channel->SetSendRtpHeaderExtensions(extensions));
306
307 // Set capturer.
308 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer));
309
310 // Verify capturer has turned off applying rotation.
311 EXPECT_FALSE(capturer.GetApplyRotation());
312
313 // Verify removing header extension turns on applying rotation.
314 extensions.clear();
315 EXPECT_TRUE(channel->SetSendRtpHeaderExtensions(extensions));
316 EXPECT_TRUE(capturer.GetApplyRotation());
317}
318
319TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionAfterCapturer) {
320 cricket::FakeVideoCapturer capturer;
321
322 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
323 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
324 std::vector<cricket::VideoCodec> codecs;
325 codecs.push_back(kVp8Codec);
326
327 rtc::scoped_ptr<VideoMediaChannel> channel(
328 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
329 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
330
331 // Set capturer.
332 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer));
333
334 // Add CVO extension.
335 const int id = 1;
336 std::vector<cricket::RtpHeaderExtension> extensions;
337 extensions.push_back(
338 cricket::RtpHeaderExtension(kRtpVideoRotationHeaderExtension, id));
339 EXPECT_TRUE(channel->SetSendRtpHeaderExtensions(extensions));
340
341 // Verify capturer has turned off applying rotation.
342 EXPECT_FALSE(capturer.GetApplyRotation());
343
344 // Verify removing header extension turns on applying rotation.
345 extensions.clear();
346 EXPECT_TRUE(channel->SetSendRtpHeaderExtensions(extensions));
347 EXPECT_TRUE(capturer.GetApplyRotation());
348}
349
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000350TEST_F(WebRtcVideoEngine2Test, SetSendFailsBeforeSettingCodecs) {
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200351 engine_.Init();
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000352 rtc::scoped_ptr<VideoMediaChannel> channel(
353 engine_.CreateChannel(cricket::VideoOptions(), NULL));
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000354
355 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
356
357 EXPECT_FALSE(channel->SetSend(true))
358 << "Channel should not start without codecs.";
359 EXPECT_TRUE(channel->SetSend(false))
360 << "Channel should be stoppable even without set codecs.";
361}
362
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000363TEST_F(WebRtcVideoEngine2Test, GetStatsWithoutSendCodecsSetDoesNotCrash) {
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200364 engine_.Init();
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000365 rtc::scoped_ptr<VideoMediaChannel> channel(
366 engine_.CreateChannel(cricket::VideoOptions(), NULL));
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000367 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
368 VideoMediaInfo info;
369 channel->GetStats(&info);
370}
371
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000372TEST_F(WebRtcVideoEngine2Test, UseExternalFactoryForVp8WhenSupported) {
373 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
374 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
375 std::vector<cricket::VideoCodec> codecs;
376 codecs.push_back(kVp8Codec);
377
378 rtc::scoped_ptr<VideoMediaChannel> channel(
379 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
380
381 EXPECT_TRUE(
382 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
383 ASSERT_EQ(1u, encoder_factory.encoders().size());
384 EXPECT_TRUE(channel->SetSend(true));
385
386 cricket::FakeVideoCapturer capturer;
387 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer));
388 EXPECT_EQ(cricket::CS_RUNNING,
389 capturer.Start(capturer.GetSupportedFormats()->front()));
390 EXPECT_TRUE(capturer.CaptureFrame());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000391 EXPECT_TRUE_WAIT(encoder_factory.encoders()[0]->GetNumEncodedFrames() > 0,
392 kTimeout);
393
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000394 // Sending one frame will have reallocated the encoder since input size
395 // changes from a small default to the actual frame width/height.
396 int num_created_encoders = encoder_factory.GetNumCreatedEncoders();
397 EXPECT_EQ(num_created_encoders, 2);
398
399 // Setting codecs of the same type should not reallocate any encoders
400 // (expecting a no-op).
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000401 EXPECT_TRUE(channel->SetSendCodecs(codecs));
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000402 EXPECT_EQ(num_created_encoders, encoder_factory.GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000403
404 // Remove stream previously added to free the external encoder instance.
405 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
406 EXPECT_EQ(0u, encoder_factory.encoders().size());
407}
408
Peter Boström53eda3d2015-03-27 15:53:18 +0100409TEST_F(WebRtcVideoEngine2Test, CanConstructDecoderForVp9EncoderFactory) {
410 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
411 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP9, "VP9");
412 std::vector<cricket::VideoCodec> codecs;
413 codecs.push_back(kVp9Codec);
414
415 rtc::scoped_ptr<VideoMediaChannel> channel(
416 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
417
418 EXPECT_TRUE(
419 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
420}
421
qiangchenc27d89f2015-07-16 10:27:16 -0700422TEST_F(WebRtcVideoEngine2Test, PropagatesInputFrameTimestamp) {
423 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
424 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
425 std::vector<cricket::VideoCodec> codecs;
426 codecs.push_back(kVp8Codec);
427
428 FakeCallFactory factory;
429 engine_.SetCallFactory(&factory);
430 rtc::scoped_ptr<VideoMediaChannel> channel(
431 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
432
433 EXPECT_TRUE(
434 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
435
436 FakeVideoCapturer capturer;
437 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer));
438 capturer.Start(cricket::VideoFormat(1280, 720,
439 cricket::VideoFormat::FpsToInterval(60),
440 cricket::FOURCC_I420));
441 channel->SetSend(true);
442
pbos1cb121d2015-09-14 11:38:38 -0700443 FakeVideoSendStream* stream = factory.GetCall()->GetVideoSendStreams()[0];
qiangchenc27d89f2015-07-16 10:27:16 -0700444
qiangchenc27d89f2015-07-16 10:27:16 -0700445
446 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700447 int64_t last_timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700448 for (int i = 0; i < 10; i++) {
449 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700450 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700451 int64_t interval = timestamp - last_timestamp;
452
453 // Precision changes from nanosecond to millisecond.
454 // Allow error to be no more than 1.
455 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1);
456
457 last_timestamp = timestamp;
458 }
459
460 capturer.Start(cricket::VideoFormat(1280, 720,
461 cricket::VideoFormat::FpsToInterval(30),
462 cricket::FOURCC_I420));
463
464 EXPECT_TRUE(capturer.CaptureFrame());
465 last_timestamp = stream->GetLastTimestamp();
466 for (int i = 0; i < 10; i++) {
467 EXPECT_TRUE(capturer.CaptureFrame());
pbos1cb121d2015-09-14 11:38:38 -0700468 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700469 int64_t interval = timestamp - last_timestamp;
470
471 // Precision changes from nanosecond to millisecond.
472 // Allow error to be no more than 1.
473 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1);
474
475 last_timestamp = timestamp;
476 }
477
478 // Remove stream previously added to free the external encoder instance.
479 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
480}
481
pbos1cb121d2015-09-14 11:38:38 -0700482TEST_F(WebRtcVideoEngine2Test,
483 ProducesIncreasingTimestampsWithResetInputSources) {
484 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
485 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
486 std::vector<cricket::VideoCodec> codecs;
487 codecs.push_back(kVp8Codec);
488
489 FakeCallFactory factory;
490 engine_.SetCallFactory(&factory);
491 rtc::scoped_ptr<VideoMediaChannel> channel(
492 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
493
494 EXPECT_TRUE(
495 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
496 channel->SetSend(true);
497 FakeVideoSendStream* stream = factory.GetCall()->GetVideoSendStreams()[0];
498
499 FakeVideoCapturer capturer1;
500 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer1));
501
502 cricket::CapturedFrame frame;
503 frame.width = 1280;
504 frame.height = 720;
505 frame.fourcc = cricket::FOURCC_I420;
506 frame.data_size = static_cast<uint32>(
507 cricket::VideoFrame::SizeOf(frame.width, frame.height));
508 rtc::scoped_ptr<char[]> data(new char[frame.data_size]);
509 frame.data = data.get();
510 memset(frame.data, 1, frame.data_size);
511 frame.elapsed_time = 0;
512 const int kInitialTimestamp = 123456;
513 frame.time_stamp = kInitialTimestamp;
514
515 // Deliver initial frame.
516 capturer1.SignalCapturedFrame(&frame);
517 // Deliver next frame 1 second later.
518 frame.time_stamp += rtc::kNumNanosecsPerSec;
519 rtc::Thread::Current()->SleepMs(1000);
520 capturer1.SignalCapturedFrame(&frame);
521
522 int64_t capturer1_last_timestamp = stream->GetLastTimestamp();
523 // Reset input source, should still be continuous even though input-frame
524 // timestamp is less than before.
525 FakeVideoCapturer capturer2;
526 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer2));
527
528 rtc::Thread::Current()->SleepMs(1);
529 // Deliver with a timestamp (10 seconds) before the previous initial one,
530 // these should not be related at all anymore and it should still work fine.
531 frame.time_stamp = kInitialTimestamp - 10000;
532 capturer2.SignalCapturedFrame(&frame);
533
534 // New timestamp should be at least 1ms in the future and not old.
535 EXPECT_GT(stream->GetLastTimestamp(), capturer1_last_timestamp);
536
537 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
538}
539
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000540VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalEncoderFactory(
541 cricket::WebRtcVideoEncoderFactory* encoder_factory,
542 const std::vector<VideoCodec>& codecs) {
543 engine_.SetExternalEncoderFactory(encoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200544 engine_.Init();
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000545
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000546 VideoMediaChannel* channel =
547 engine_.CreateChannel(cricket::VideoOptions(), NULL);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000548 EXPECT_TRUE(channel->SetSendCodecs(codecs));
549
550 return channel;
551}
552
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000553VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalDecoderFactory(
554 cricket::WebRtcVideoDecoderFactory* decoder_factory,
555 const std::vector<VideoCodec>& codecs) {
556 engine_.SetExternalDecoderFactory(decoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200557 engine_.Init();
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000558
559 VideoMediaChannel* channel =
560 engine_.CreateChannel(cricket::VideoOptions(), NULL);
561 EXPECT_TRUE(channel->SetRecvCodecs(codecs));
562
563 return channel;
564}
565
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000566TEST_F(WebRtcVideoEngine2Test, UsesSimulcastAdapterForVp8Factories) {
567 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
568 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
569 std::vector<cricket::VideoCodec> codecs;
570 codecs.push_back(kVp8Codec);
571
572 rtc::scoped_ptr<VideoMediaChannel> channel(
573 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
574
575 std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs3);
576
577 EXPECT_TRUE(
578 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
579 EXPECT_TRUE(channel->SetSend(true));
580
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000581 cricket::FakeVideoCapturer capturer;
582 EXPECT_TRUE(channel->SetCapturer(ssrcs.front(), &capturer));
583 EXPECT_EQ(cricket::CS_RUNNING,
584 capturer.Start(capturer.GetSupportedFormats()->front()));
585 EXPECT_TRUE(capturer.CaptureFrame());
586
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000587 EXPECT_GT(encoder_factory.encoders().size(), 1u);
588
589 // Verify that encoders are configured for simulcast through adapter
590 // (increasing resolution and only configured to send one stream each).
591 int prev_width = -1;
592 for (size_t i = 0; i < encoder_factory.encoders().size(); ++i) {
593 webrtc::VideoCodec codec_settings =
594 encoder_factory.encoders()[i]->GetCodecSettings();
595 EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
596 EXPECT_GT(codec_settings.width, prev_width);
597 prev_width = codec_settings.width;
598 }
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000599
600 EXPECT_TRUE(channel->SetCapturer(ssrcs.front(), NULL));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000601
602 channel.reset();
603 ASSERT_EQ(0u, encoder_factory.encoders().size());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000604}
605
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000606TEST_F(WebRtcVideoEngine2Test, ChannelWithExternalH264CanChangeToInternalVp8) {
607 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
608 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
609 std::vector<cricket::VideoCodec> codecs;
610 codecs.push_back(kH264Codec);
611
612 rtc::scoped_ptr<VideoMediaChannel> channel(
613 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
614
615 EXPECT_TRUE(
616 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
617 ASSERT_EQ(1u, encoder_factory.encoders().size());
618
619 codecs.clear();
620 codecs.push_back(kVp8Codec);
621 EXPECT_TRUE(channel->SetSendCodecs(codecs));
622
623 ASSERT_EQ(0u, encoder_factory.encoders().size());
624}
625
626TEST_F(WebRtcVideoEngine2Test,
627 DontUseExternalEncoderFactoryForUnsupportedCodecs) {
628 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
629 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
630 std::vector<cricket::VideoCodec> codecs;
631 codecs.push_back(kVp8Codec);
632
633 rtc::scoped_ptr<VideoMediaChannel> channel(
634 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
635
636 EXPECT_TRUE(
637 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000638 // Make sure DestroyVideoEncoder was called on the factory.
639 ASSERT_EQ(0u, encoder_factory.encoders().size());
640}
641
642TEST_F(WebRtcVideoEngine2Test,
643 UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
644 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
645 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
646 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
647
648 std::vector<cricket::VideoCodec> codecs;
649 codecs.push_back(kVp8Codec);
650
651 rtc::scoped_ptr<VideoMediaChannel> channel(
652 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
653
654 std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs3);
655
656 EXPECT_TRUE(
657 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
658 EXPECT_TRUE(channel->SetSend(true));
659
660 // Send a fake frame, or else the media engine will configure the simulcast
661 // encoder adapter at a low-enough size that it'll only create a single
662 // encoder layer.
663 cricket::FakeVideoCapturer capturer;
664 EXPECT_TRUE(channel->SetCapturer(ssrcs.front(), &capturer));
665 EXPECT_EQ(cricket::CS_RUNNING,
666 capturer.Start(capturer.GetSupportedFormats()->front()));
667 EXPECT_TRUE(capturer.CaptureFrame());
668
669 ASSERT_GT(encoder_factory.encoders().size(), 1u);
670 EXPECT_EQ(webrtc::kVideoCodecVP8,
671 encoder_factory.encoders()[0]->GetCodecSettings().codecType);
672
673 channel.reset();
674 // Make sure DestroyVideoEncoder was called on the factory.
675 EXPECT_EQ(0u, encoder_factory.encoders().size());
676}
677
678TEST_F(WebRtcVideoEngine2Test,
679 DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
680 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
681 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
682 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
683
684 std::vector<cricket::VideoCodec> codecs;
685 codecs.push_back(kH264Codec);
686
687 rtc::scoped_ptr<VideoMediaChannel> channel(
688 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
689
690 EXPECT_TRUE(
691 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
692 ASSERT_EQ(1u, encoder_factory.encoders().size());
693 EXPECT_EQ(webrtc::kVideoCodecH264,
694 encoder_factory.encoders()[0]->GetCodecSettings().codecType);
695
696 channel.reset();
697 // Make sure DestroyVideoEncoder was called on the factory.
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000698 ASSERT_EQ(0u, encoder_factory.encoders().size());
699}
700
noahricfdac5162015-08-27 01:59:29 -0700701TEST_F(WebRtcVideoEngine2Test, SimulcastDisabledForH264) {
702 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
703 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
704 std::vector<cricket::VideoCodec> codecs;
705 codecs.push_back(kH264Codec);
706
707 rtc::scoped_ptr<VideoMediaChannel> channel(
708 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
709
710 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs3);
711 EXPECT_TRUE(
712 channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs)));
713 // Set the stream to 720p. This should trigger a "real" encoder
714 // initialization.
715 cricket::VideoFormat format(
716 1280, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
717 EXPECT_TRUE(channel->SetSendStreamFormat(ssrcs[0], format));
718 ASSERT_EQ(1u, encoder_factory.encoders().size());
719 FakeWebRtcVideoEncoder* encoder = encoder_factory.encoders()[0];
720 EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
721 EXPECT_EQ(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
722}
723
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000724// Test external codec with be added to the end of the supported codec list.
725TEST_F(WebRtcVideoEngine2Test, ReportSupportedExternalCodecs) {
726 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
727 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
728 engine_.SetExternalEncoderFactory(&encoder_factory);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200729 engine_.Init();
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000730
731 std::vector<cricket::VideoCodec> codecs(engine_.codecs());
732 ASSERT_GE(codecs.size(), 2u);
733 cricket::VideoCodec internal_codec = codecs.front();
734 cricket::VideoCodec external_codec = codecs.back();
735
736 // The external codec will appear at last.
737 EXPECT_EQ("VP8", internal_codec.name);
738 EXPECT_EQ("H264", external_codec.name);
739}
740
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000741TEST_F(WebRtcVideoEngine2Test, RegisterExternalDecodersIfSupported) {
742 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
743 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
744 std::vector<cricket::VideoCodec> codecs;
745 codecs.push_back(kVp8Codec);
746
747 rtc::scoped_ptr<VideoMediaChannel> channel(
748 SetUpForExternalDecoderFactory(&decoder_factory, codecs));
749
750 EXPECT_TRUE(
751 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
752 ASSERT_EQ(1u, decoder_factory.decoders().size());
753
754 // Setting codecs of the same type should not reallocate the decoder.
755 EXPECT_TRUE(channel->SetRecvCodecs(codecs));
756 EXPECT_EQ(1, decoder_factory.GetNumCreatedDecoders());
757
758 // Remove stream previously added to free the external decoder instance.
759 EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
760 EXPECT_EQ(0u, decoder_factory.decoders().size());
761}
762
763// Verifies that we can set up decoders that are not internally supported.
764TEST_F(WebRtcVideoEngine2Test, RegisterExternalH264DecoderIfSupported) {
765 // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We
766 // can't even query the WebRtcVideoDecoderFactory for supported codecs.
767 // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
768 // codecs.
769 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
770 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
771 engine_.SetExternalEncoderFactory(&encoder_factory);
772 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
773 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264);
774 std::vector<cricket::VideoCodec> codecs;
775 codecs.push_back(kH264Codec);
776
777 rtc::scoped_ptr<VideoMediaChannel> channel(
778 SetUpForExternalDecoderFactory(&decoder_factory, codecs));
779
780 EXPECT_TRUE(
781 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
782 ASSERT_EQ(1u, decoder_factory.decoders().size());
783}
784
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000785class WebRtcVideoEngine2BaseTest
786 : public VideoEngineTest<cricket::WebRtcVideoEngine2> {
787 protected:
788 typedef VideoEngineTest<cricket::WebRtcVideoEngine2> Base;
789};
790
791#define WEBRTC_ENGINE_BASE_TEST(test) \
792 TEST_F(WebRtcVideoEngine2BaseTest, test) { Base::test##Body(); }
793
794WEBRTC_ENGINE_BASE_TEST(ConstrainNewCodec2);
795
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000796class WebRtcVideoChannel2BaseTest
797 : public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> {
798 protected:
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000799 typedef VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> Base;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000800
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000801 cricket::VideoCodec DefaultCodec() override { return kVp8Codec; }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000802};
803
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000804#define WEBRTC_BASE_TEST(test) \
805 TEST_F(WebRtcVideoChannel2BaseTest, test) { Base::test(); }
806
807#define WEBRTC_DISABLED_BASE_TEST(test) \
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000808 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_##test) { Base::test(); }
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000809
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000810WEBRTC_BASE_TEST(SetSend);
811WEBRTC_BASE_TEST(SetSendWithoutCodecs);
812WEBRTC_BASE_TEST(SetSendSetsTransportBufferSizes);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000813
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000814WEBRTC_BASE_TEST(GetStats);
815WEBRTC_BASE_TEST(GetStatsMultipleRecvStreams);
816WEBRTC_BASE_TEST(GetStatsMultipleSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000817
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000818WEBRTC_BASE_TEST(SetSendBandwidth);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000819
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000820WEBRTC_BASE_TEST(SetSendSsrc);
821WEBRTC_BASE_TEST(SetSendSsrcAfterSetCodecs);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000822
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000823WEBRTC_BASE_TEST(SetRenderer);
824WEBRTC_BASE_TEST(AddRemoveRecvStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000825
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000826WEBRTC_DISABLED_BASE_TEST(AddRemoveRecvStreamAndRender);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000827
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000828WEBRTC_BASE_TEST(AddRemoveRecvStreamsNoConference);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000829
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000830WEBRTC_BASE_TEST(AddRemoveSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000831
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000832WEBRTC_BASE_TEST(SimulateConference);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000833
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000834WEBRTC_BASE_TEST(AddRemoveCapturer);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000835
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000836WEBRTC_BASE_TEST(RemoveCapturerWithoutAdd);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000837
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000838WEBRTC_BASE_TEST(AddRemoveCapturerMultipleSources);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000839
840// TODO(pbos): Figure out why this fails so often.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000841WEBRTC_DISABLED_BASE_TEST(HighAspectHighHeightCapturer);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000842
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000843WEBRTC_BASE_TEST(RejectEmptyStreamParams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000844
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000845WEBRTC_BASE_TEST(AdaptResolution16x10);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000846
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000847WEBRTC_BASE_TEST(AdaptResolution4x3);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000848
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000849// TODO(juberti): Restore this test once we support sending 0 fps.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000850WEBRTC_DISABLED_BASE_TEST(AdaptDropAllFrames);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000851// TODO(juberti): Understand why we get decode errors on this test.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000852WEBRTC_DISABLED_BASE_TEST(AdaptFramerate);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000853
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +0000854WEBRTC_BASE_TEST(SendsLowerResolutionOnSmallerFrames);
855
856WEBRTC_BASE_TEST(MuteStream);
857
858WEBRTC_BASE_TEST(MultipleSendStreams);
859
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000860WEBRTC_BASE_TEST(SetSendStreamFormat0x0);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000861
862// TODO(zhurunz): Fix the flakey test.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000863WEBRTC_DISABLED_BASE_TEST(SetSendStreamFormat);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000864
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000865TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Vga) {
866 SendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30, 0));
867}
868
869TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Qvga) {
870 SendAndReceive(cricket::VideoCodec(100, "VP8", 320, 200, 30, 0));
871}
872
873TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8SvcQqvga) {
874 SendAndReceive(cricket::VideoCodec(100, "VP8", 160, 100, 30, 0));
875}
876
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000877TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) {
878 Base::TwoStreamsSendAndReceive(kVp8Codec);
879}
880
881TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsReUseFirstStream) {
882 Base::TwoStreamsReUseFirstStream(kVp8Codec);
883}
884
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000885WEBRTC_BASE_TEST(SendManyResizeOnce);
886
887// TODO(pbos): Enable and figure out why this fails (or should work).
888TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_SendVp8HdAndReceiveAdaptedVp8Vga) {
889 EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
890 EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
891 channel_->UpdateAspectRatio(1280, 720);
892 video_capturer_.reset(new cricket::FakeVideoCapturer);
893 const std::vector<cricket::VideoFormat>* formats =
894 video_capturer_->GetSupportedFormats();
895 cricket::VideoFormat capture_format_hd = (*formats)[0];
896 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format_hd));
897 EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get()));
898
899 // Capture format HD -> adapt (OnOutputFormatRequest VGA) -> VGA.
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +0000900 cricket::VideoCodec codec = kVp8Codec720p;
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000901 EXPECT_TRUE(SetOneCodec(codec));
902 codec.width /= 2;
903 codec.height /= 2;
904 EXPECT_TRUE(SetSend(true));
905 EXPECT_TRUE(channel_->SetRender(true));
906 EXPECT_EQ(0, renderer_.num_rendered_frames());
907 EXPECT_TRUE(SendFrame());
908 EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
909}
910
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000911class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test,
912 public WebRtcCallFactory {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000913 public:
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +0200914 WebRtcVideoChannel2Test() : fake_call_(NULL), last_ssrc_(0) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000915 void SetUp() override {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000916 engine_.SetCallFactory(this);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200917 engine_.Init();
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000918 channel_.reset(engine_.CreateChannel(cricket::VideoOptions(), NULL));
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000919 ASSERT_TRUE(fake_call_ != NULL) << "Call not created through factory.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000920 last_ssrc_ = 123;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000921 ASSERT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000922 }
923
924 protected:
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +0200925 virtual std::vector<cricket::VideoCodec> GetCodecs() {
926 return engine_.codecs();
927 }
928
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000929 webrtc::Call* CreateCall(const webrtc::Call::Config& config) override {
Fredrik Solenbergd3ddc1b2015-05-07 17:07:34 +0200930 DCHECK(fake_call_ == NULL);
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000931 fake_call_ = new FakeCall(config);
932 return fake_call_;
933 }
934
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000935 FakeVideoSendStream* AddSendStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000936 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000937 }
938
939 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000940 size_t num_streams = fake_call_->GetVideoSendStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000941 EXPECT_TRUE(channel_->AddSendStream(sp));
942 std::vector<FakeVideoSendStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000943 fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000944 EXPECT_EQ(num_streams + 1, streams.size());
945 return streams[streams.size() - 1];
946 }
947
948 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000949 return fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000950 }
951
952 FakeVideoReceiveStream* AddRecvStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000953 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000954 }
955
956 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000957 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000958 EXPECT_TRUE(channel_->AddRecvStream(sp));
959 std::vector<FakeVideoReceiveStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000960 fake_call_->GetVideoReceiveStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000961 EXPECT_EQ(num_streams + 1, streams.size());
962 return streams[streams.size() - 1];
963 }
964
pbos@webrtc.org00873182014-11-25 14:03:34 +0000965 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
966 int expected_min_bitrate_bps,
967 const char* start_bitrate_kbps,
968 int expected_start_bitrate_bps,
969 const char* max_bitrate_kbps,
970 int expected_max_bitrate_bps) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000971 std::vector<VideoCodec> codecs;
972 codecs.push_back(kVp8Codec);
pbos@webrtc.org00873182014-11-25 14:03:34 +0000973 codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps;
974 codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps;
975 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000976 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
977
pbos@webrtc.org00873182014-11-25 14:03:34 +0000978 EXPECT_EQ(expected_min_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +0100979 fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +0000980 EXPECT_EQ(expected_start_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +0100981 fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +0000982 EXPECT_EQ(expected_max_bitrate_bps,
Stefan Holmere5904162015-03-26 11:11:06 +0100983 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000984 }
985
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000986 void TestSetSendRtpHeaderExtensions(const std::string& cricket_ext,
987 const std::string& webrtc_ext) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000988 FakeCall* call = fake_call_;
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000989 // Enable extension.
990 const int id = 1;
991 std::vector<cricket::RtpHeaderExtension> extensions;
992 extensions.push_back(cricket::RtpHeaderExtension(cricket_ext, id));
993 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
994
995 FakeVideoSendStream* send_stream =
996 AddSendStream(cricket::StreamParams::CreateLegacy(123));
997
998 // Verify the send extension id.
999 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1000 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
1001 EXPECT_EQ(webrtc_ext, send_stream->GetConfig().rtp.extensions[0].name);
1002 // Verify call with same set of extensions returns true.
1003 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
1004 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
1005 // receivers.
1006 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
1007 ->GetConfig()
1008 .rtp.extensions.empty());
1009
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001010 // Verify that existing RTP header extensions can be removed.
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001011 std::vector<cricket::RtpHeaderExtension> empty_extensions;
1012 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(empty_extensions));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001013 ASSERT_EQ(1u, call->GetVideoSendStreams().size());
1014 send_stream = call->GetVideoSendStreams()[0];
1015 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
1016
1017 // Verify that adding receive RTP header extensions adds them for existing
1018 // streams.
1019 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
1020 send_stream = call->GetVideoSendStreams()[0];
1021 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1022 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
1023 EXPECT_EQ(webrtc_ext, send_stream->GetConfig().rtp.extensions[0].name);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001024 }
1025
1026 void TestSetRecvRtpHeaderExtensions(const std::string& cricket_ext,
1027 const std::string& webrtc_ext) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001028 FakeCall* call = fake_call_;
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001029 // Enable extension.
1030 const int id = 1;
1031 std::vector<cricket::RtpHeaderExtension> extensions;
1032 extensions.push_back(cricket::RtpHeaderExtension(cricket_ext, id));
1033 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
1034
1035 FakeVideoReceiveStream* recv_stream =
1036 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1037
1038 // Verify the recv extension id.
1039 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1040 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
1041 EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name);
1042 // Verify call with same set of extensions returns true.
1043 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001044
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001045 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
1046 // senders.
1047 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
1048 ->GetConfig()
1049 .rtp.extensions.empty());
1050
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001051 // Verify that existing RTP header extensions can be removed.
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001052 std::vector<cricket::RtpHeaderExtension> empty_extensions;
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001053 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(empty_extensions));
1054 ASSERT_EQ(1u, call->GetVideoReceiveStreams().size());
1055 recv_stream = call->GetVideoReceiveStreams()[0];
1056 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
1057
1058 // Verify that adding receive RTP header extensions adds them for existing
1059 // streams.
1060 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
1061 recv_stream = call->GetVideoReceiveStreams()[0];
1062 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1063 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
1064 EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001065 }
1066
Erik SprĂ¥ngefbde372015-04-29 16:21:28 +02001067 void TestCpuAdaptation(bool enable_overuse, bool is_screenshare);
Peter Boström3548dd22015-05-22 18:48:36 +02001068 void TestReceiverLocalSsrcConfiguration(bool receiver_first);
noahricd10a68e2015-07-10 11:27:55 -07001069 void TestReceiveUnsignalledSsrcPacket(uint8_t payload_type,
1070 bool expect_created_receive_stream);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001071
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001072 FakeVideoSendStream* SetDenoisingOption(bool enabled) {
1073 VideoOptions options;
1074 options.video_noise_reduction.Set(enabled);
1075 channel_->SetOptions(options);
1076 return fake_call_->GetVideoSendStreams().back();
1077 }
1078
Peter Boström2feafdb2015-09-09 14:32:14 +02001079 FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) {
1080 const int kRtxSsrcOffset = 0xDEADBEEF;
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001081 last_ssrc_ += 3;
Peter Boström2feafdb2015-09-09 14:32:14 +02001082 std::vector<uint32_t> ssrcs;
1083 std::vector<uint32_t> rtx_ssrcs;
1084 uint32_t num_streams = enabled ? 3 : 1;
1085 for (uint32_t i = 0; i < num_streams; ++i) {
1086 uint32_t ssrc = last_ssrc_ + i;
1087 ssrcs.push_back(ssrc);
1088 if (with_rtx) {
1089 rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset);
1090 }
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001091 }
Peter Boström2feafdb2015-09-09 14:32:14 +02001092 if (with_rtx) {
1093 return AddSendStream(
1094 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1095 }
1096 return AddSendStream(CreateSimStreamParams("cname", ssrcs));
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001097 }
1098
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001099 FakeCall* fake_call_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001100 rtc::scoped_ptr<VideoMediaChannel> channel_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001101 uint32 last_ssrc_;
1102};
1103
pbos8fc7fa72015-07-15 08:02:58 -07001104TEST_F(WebRtcVideoChannel2Test, SetsSyncGroupFromSyncLabel) {
1105 const uint32 kVideoSsrc = 123;
1106 const std::string kSyncLabel = "AvSyncLabel";
1107
1108 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc);
1109 sp.sync_label = kSyncLabel;
1110 EXPECT_TRUE(channel_->AddRecvStream(sp));
1111
1112 EXPECT_EQ(1, fake_call_->GetVideoReceiveStreams().size());
1113 EXPECT_EQ(kSyncLabel,
1114 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group)
1115 << "SyncGroup should be set based on sync_label";
1116}
1117
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001118TEST_F(WebRtcVideoChannel2Test, RecvStreamWithSimAndRtx) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001119 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1120 EXPECT_TRUE(channel_->SetSend(true));
1121 cricket::VideoOptions options;
1122 options.conference_mode.Set(true);
1123 EXPECT_TRUE(channel_->SetOptions(options));
1124
1125 // Send side.
1126 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
1127 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
1128 FakeVideoSendStream* send_stream = AddSendStream(
1129 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1130
1131 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
1132 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
1133 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
1134
1135 // Receiver side.
1136 FakeVideoReceiveStream* recv_stream = AddRecvStream(
1137 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1138 ASSERT_GT(recv_stream->GetConfig().rtp.rtx.size(), 0u)
1139 << "No SSRCs for RTX configured by AddRecvStream.";
1140 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size())
1141 << "This test only works with one receive codec. Please update the test.";
1142 EXPECT_EQ(rtx_ssrcs[0],
1143 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
1144 // TODO(pbos): Make sure we set the RTX for correct payloads etc.
1145}
1146
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001147TEST_F(WebRtcVideoChannel2Test, RecvStreamWithRtx) {
1148 // Setup one channel with an associated RTX stream.
1149 cricket::StreamParams params =
1150 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
1151 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
1152 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
1153 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size());
1154 EXPECT_EQ(kRtxSsrcs1[0],
1155 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001156}
1157
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001158TEST_F(WebRtcVideoChannel2Test, RecvStreamNoRtx) {
1159 // Setup one channel without an associated RTX stream.
1160 cricket::StreamParams params =
1161 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
1162 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
1163 ASSERT_TRUE(recv_stream->GetConfig().rtp.rtx.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001164}
1165
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001166TEST_F(WebRtcVideoChannel2Test, NoHeaderExtesionsByDefault) {
1167 FakeVideoSendStream* send_stream =
1168 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
1169 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
1170
1171 FakeVideoReceiveStream* recv_stream =
1172 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
1173 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001174}
1175
pbos@webrtc.org587ef602014-06-16 17:32:02 +00001176// Test support for RTP timestamp offset header extension.
1177TEST_F(WebRtcVideoChannel2Test, SendRtpTimestampOffsetHeaderExtensions) {
1178 TestSetSendRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension,
1179 webrtc::RtpExtension::kTOffset);
1180}
1181TEST_F(WebRtcVideoChannel2Test, RecvRtpTimestampOffsetHeaderExtensions) {
1182 TestSetRecvRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension,
1183 webrtc::RtpExtension::kTOffset);
1184}
1185
1186// Test support for absolute send time header extension.
1187TEST_F(WebRtcVideoChannel2Test, SendAbsoluteSendTimeHeaderExtensions) {
1188 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension,
1189 webrtc::RtpExtension::kAbsSendTime);
1190}
1191TEST_F(WebRtcVideoChannel2Test, RecvAbsoluteSendTimeHeaderExtensions) {
1192 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension,
1193 webrtc::RtpExtension::kAbsSendTime);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001194}
1195
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001196// Test support for video rotation header extension.
1197TEST_F(WebRtcVideoChannel2Test, SendVideoRotationHeaderExtensions) {
1198 TestSetSendRtpHeaderExtensions(kRtpVideoRotationHeaderExtension,
1199 webrtc::RtpExtension::kVideoRotation);
1200}
1201TEST_F(WebRtcVideoChannel2Test, RecvVideoRotationHeaderExtensions) {
1202 TestSetRecvRtpHeaderExtensions(kRtpVideoRotationHeaderExtension,
1203 webrtc::RtpExtension::kVideoRotation);
1204}
1205
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001206TEST_F(WebRtcVideoChannel2Test, IdenticalSendExtensionsDoesntRecreateStream) {
1207 const int kTOffsetId = 1;
1208 const int kAbsSendTimeId = 2;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001209 const int kVideoRotationId = 3;
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001210 std::vector<cricket::RtpHeaderExtension> extensions;
1211 extensions.push_back(cricket::RtpHeaderExtension(
1212 kRtpAbsoluteSenderTimeHeaderExtension, kAbsSendTimeId));
1213 extensions.push_back(cricket::RtpHeaderExtension(
1214 kRtpTimestampOffsetHeaderExtension, kTOffsetId));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001215 extensions.push_back(cricket::RtpHeaderExtension(
1216 kRtpVideoRotationHeaderExtension, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001217
1218 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
1219 FakeVideoSendStream* send_stream =
1220 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1221
1222 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001223 ASSERT_EQ(3u, send_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001224
1225 // Setting the same extensions (even if in different order) shouldn't
1226 // reallocate the stream.
1227 std::reverse(extensions.begin(), extensions.end());
1228 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
1229
1230 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1231
1232 // Setting different extensions should recreate the stream.
1233 extensions.resize(1);
1234 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
1235
1236 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
1237}
1238
1239TEST_F(WebRtcVideoChannel2Test, IdenticalRecvExtensionsDoesntRecreateStream) {
1240 const int kTOffsetId = 1;
1241 const int kAbsSendTimeId = 2;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001242 const int kVideoRotationId = 3;
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001243 std::vector<cricket::RtpHeaderExtension> extensions;
1244 extensions.push_back(cricket::RtpHeaderExtension(
1245 kRtpAbsoluteSenderTimeHeaderExtension, kAbsSendTimeId));
1246 extensions.push_back(cricket::RtpHeaderExtension(
1247 kRtpTimestampOffsetHeaderExtension, kTOffsetId));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07001248 extensions.push_back(cricket::RtpHeaderExtension(
1249 kRtpVideoRotationHeaderExtension, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001250
1251 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
Peter Boström54be3e02015-05-25 15:04:24 +02001252 FakeVideoReceiveStream* recv_stream =
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001253 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1254
1255 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Peter Boström54be3e02015-05-25 15:04:24 +02001256 ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00001257
1258 // Setting the same extensions (even if in different order) shouldn't
1259 // reallocate the stream.
1260 std::reverse(extensions.begin(), extensions.end());
1261 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
1262
1263 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
1264
1265 // Setting different extensions should recreate the stream.
1266 extensions.resize(1);
1267 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
1268
1269 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
1270}
1271
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001272TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001273 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001274 const int kUnsupportedId = 1;
1275 const int kTOffsetId = 2;
1276
1277 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001278 extensions.push_back(
1279 cricket::RtpHeaderExtension(kUnsupportedExtensionName, kUnsupportedId));
1280 extensions.push_back(
1281 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, kTOffsetId));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001282 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
1283 FakeVideoSendStream* send_stream =
1284 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1285
1286 // Only timestamp offset extension is set to send stream,
1287 // unsupported rtp extension is ignored.
1288 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1289 EXPECT_STREQ(webrtc::RtpExtension::kTOffset,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001290 send_stream->GetConfig().rtp.extensions[0].name.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001291}
1292
1293TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001294 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001295 const int kUnsupportedId = 1;
1296 const int kTOffsetId = 2;
1297
1298 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001299 extensions.push_back(
1300 cricket::RtpHeaderExtension(kUnsupportedExtensionName, kUnsupportedId));
1301 extensions.push_back(
1302 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, kTOffsetId));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001303 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
1304 FakeVideoReceiveStream* recv_stream =
1305 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1306
1307 // Only timestamp offset extension is set to receive stream,
1308 // unsupported rtp extension is ignored.
1309 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1310 EXPECT_STREQ(webrtc::RtpExtension::kTOffset,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001311 recv_stream->GetConfig().rtp.extensions[0].name.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001312}
1313
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001314TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02001315 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00001316 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001317 std::vector<cricket::RtpHeaderExtension> extensions;
1318 extensions.push_back(cricket::RtpHeaderExtension(
1319 webrtc::RtpExtension::kTOffset, kIncorrectIds[i]));
1320 EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions))
1321 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1322 }
1323}
1324
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001325TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02001326 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00001327 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001328 std::vector<cricket::RtpHeaderExtension> extensions;
1329 extensions.push_back(cricket::RtpHeaderExtension(
1330 webrtc::RtpExtension::kTOffset, kIncorrectIds[i]));
1331 EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions))
1332 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1333 }
1334}
1335
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001336TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001337 const int id = 1;
1338 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001339 extensions.push_back(
1340 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
1341 extensions.push_back(
1342 cricket::RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001343 EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions));
1344
1345 // Duplicate entries are also not supported.
1346 extensions.clear();
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001347 extensions.push_back(
1348 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001349 extensions.push_back(extensions.back());
1350 EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions));
1351}
1352
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001353TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001354 const int id = 1;
1355 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001356 extensions.push_back(
1357 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
1358 extensions.push_back(
1359 cricket::RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001360 EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions));
1361
1362 // Duplicate entries are also not supported.
1363 extensions.clear();
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001364 extensions.push_back(
1365 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001366 extensions.push_back(extensions.back());
1367 EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions));
1368}
1369
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001370TEST_F(WebRtcVideoChannel2Test, DISABLED_LeakyBucketTest) {
1371 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1372}
1373
1374TEST_F(WebRtcVideoChannel2Test, DISABLED_BufferedModeLatency) {
1375 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1376}
1377
1378TEST_F(WebRtcVideoChannel2Test, DISABLED_AdditiveVideoOptions) {
1379 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1380}
1381
1382TEST_F(WebRtcVideoChannel2Test, AddRecvStreamOnlyUsesOneReceiveStream) {
1383 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001384 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001385}
1386
Peter Boströmd7da1202015-06-05 14:09:38 +02001387TEST_F(WebRtcVideoChannel2Test, RtcpIsCompoundByDefault) {
1388 FakeVideoReceiveStream* stream = AddRecvStream();
1389 EXPECT_EQ(webrtc::newapi::kRtcpCompound, stream->GetConfig().rtp.rtcp_mode);
1390}
1391
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001392TEST_F(WebRtcVideoChannel2Test, RembIsEnabledByDefault) {
1393 FakeVideoReceiveStream* stream = AddRecvStream();
1394 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001395}
1396
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001397TEST_F(WebRtcVideoChannel2Test, RembCanBeEnabledAndDisabled) {
1398 FakeVideoReceiveStream* stream = AddRecvStream();
1399 EXPECT_TRUE(stream->GetConfig().rtp.remb);
1400
Peter Boström126c03e2015-05-11 12:48:12 +02001401 // Verify that REMB is turned off when send(!) codecs without REMB are set.
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001402 std::vector<VideoCodec> codecs;
1403 codecs.push_back(kVp8Codec);
1404 EXPECT_TRUE(codecs[0].feedback_params.params().empty());
Peter Boström126c03e2015-05-11 12:48:12 +02001405 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001406 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001407 EXPECT_FALSE(stream->GetConfig().rtp.remb);
1408
1409 // Verify that REMB is turned on when setting default codecs since the
1410 // default codecs have REMB enabled.
Peter Boström126c03e2015-05-11 12:48:12 +02001411 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001412 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001413 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001414}
1415
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001416TEST_F(WebRtcVideoChannel2Test, NackIsEnabledByDefault) {
1417 VerifyCodecHasDefaultFeedbackParams(default_codec_);
1418
pbos@webrtc.org19864742014-05-30 07:35:47 +00001419 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1420 EXPECT_TRUE(channel_->SetSend(true));
1421
1422 // Send side.
1423 FakeVideoSendStream* send_stream =
1424 AddSendStream(cricket::StreamParams::CreateLegacy(1));
1425 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1426
1427 // Receiver side.
1428 FakeVideoReceiveStream* recv_stream =
1429 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
1430 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1431
1432 // Nack history size should match between sender and receiver.
1433 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
1434 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001435}
1436
Peter Boström67c9df72015-05-11 14:34:58 +02001437TEST_F(WebRtcVideoChannel2Test, NackCanBeEnabledAndDisabled) {
Peter Boström67c9df72015-05-11 14:34:58 +02001438 FakeVideoSendStream* send_stream = AddSendStream();
Peter Boström3548dd22015-05-22 18:48:36 +02001439 FakeVideoReceiveStream* recv_stream = AddRecvStream();
Peter Boström67c9df72015-05-11 14:34:58 +02001440
1441 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1442 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1443
1444 // Verify that NACK is turned off when send(!) codecs without NACK are set.
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001445 std::vector<VideoCodec> codecs;
1446 codecs.push_back(kVp8Codec);
Peter Boström67c9df72015-05-11 14:34:58 +02001447 EXPECT_TRUE(codecs[0].feedback_params.params().empty());
1448 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1449 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1450 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
1451 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001452 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
1453
Peter Boström67c9df72015-05-11 14:34:58 +02001454 // Verify that NACK is turned on when setting default codecs since the
1455 // default codecs have NACK enabled.
1456 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1457 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1458 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1459 send_stream = fake_call_->GetVideoSendStreams()[0];
1460 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001461}
1462
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001463TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInterop) {
1464 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1465}
1466
1467TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInteropReversed) {
1468 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1469}
1470
1471TEST_F(WebRtcVideoChannel2Test, DISABLED_HybridNackFecConference) {
1472 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1473}
1474
1475TEST_F(WebRtcVideoChannel2Test, DISABLED_AddRemoveRecvStreamConference) {
1476 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1477}
1478
1479TEST_F(WebRtcVideoChannel2Test, DISABLED_SetRender) {
1480 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1481}
1482
1483TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAuto) {
1484 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1485}
1486
1487TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAutoCapped) {
1488 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1489}
1490
1491TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthFixed) {
1492 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1493}
1494
1495TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthInConference) {
1496 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1497}
1498
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001499TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) {
1500 static const int kScreenshareMinBitrateKbps = 800;
1501 cricket::VideoCodec codec = kVp8Codec360p;
1502 std::vector<cricket::VideoCodec> codecs;
1503 codecs.push_back(codec);
1504 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1505 VideoOptions options;
1506 options.screencast_min_bitrate.Set(kScreenshareMinBitrateKbps);
1507 channel_->SetOptions(options);
1508
1509 AddSendStream();
1510
1511 cricket::FakeVideoCapturer capturer;
1512 capturer.SetScreencast(false);
1513 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1514 cricket::VideoFormat capture_format_hd =
1515 capturer.GetSupportedFormats()->front();
1516 EXPECT_EQ(1280, capture_format_hd.width);
1517 EXPECT_EQ(720, capture_format_hd.height);
1518 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1519
1520 EXPECT_TRUE(channel_->SetSend(true));
1521
1522 EXPECT_TRUE(capturer.CaptureFrame());
1523 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1524 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1525
1526 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1527
1528 // Verify non-screencast settings.
1529 webrtc::VideoEncoderConfig encoder_config = send_stream->GetEncoderConfig();
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001530 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001531 encoder_config.content_type);
1532 EXPECT_EQ(codec.width, encoder_config.streams.front().width);
1533 EXPECT_EQ(codec.height, encoder_config.streams.front().height);
1534 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
1535 << "Non-screenshare shouldn't use min-transmit bitrate.";
1536
1537 capturer.SetScreencast(true);
1538 EXPECT_TRUE(capturer.CaptureFrame());
1539
1540 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
1541
1542 // Verify screencast settings.
1543 encoder_config = send_stream->GetEncoderConfig();
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001544 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001545 encoder_config.content_type);
1546 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
1547 encoder_config.min_transmit_bitrate_bps);
1548
1549 EXPECT_EQ(capture_format_hd.width, encoder_config.streams.front().width);
1550 EXPECT_EQ(capture_format_hd.height, encoder_config.streams.front().height);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001551 EXPECT_TRUE(encoder_config.streams[0].temporal_layer_thresholds_bps.empty());
1552
1553 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
1554}
1555
1556TEST_F(WebRtcVideoChannel2Test,
1557 ConferenceModeScreencastConfiguresTemporalLayer) {
Erik SprĂ¥ng2c4c9142015-06-24 11:24:44 +02001558 static const int kConferenceScreencastTemporalBitrateBps =
1559 ScreenshareLayerConfig::GetDefault().tl0_bitrate_kbps * 1000;
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001560 VideoOptions options;
1561 options.conference_mode.Set(true);
1562 channel_->SetOptions(options);
1563
1564 AddSendStream();
1565
1566 cricket::FakeVideoCapturer capturer;
1567 capturer.SetScreencast(true);
1568 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1569 cricket::VideoFormat capture_format_hd =
1570 capturer.GetSupportedFormats()->front();
1571 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1572
1573 EXPECT_TRUE(channel_->SetSend(true));
1574
1575 EXPECT_TRUE(capturer.CaptureFrame());
1576 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1577 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1578
1579 webrtc::VideoEncoderConfig encoder_config = send_stream->GetEncoderConfig();
1580
1581 // Verify screencast settings.
1582 encoder_config = send_stream->GetEncoderConfig();
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001583 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00001584 encoder_config.content_type);
1585 ASSERT_EQ(1u, encoder_config.streams.size());
1586 ASSERT_EQ(1u, encoder_config.streams[0].temporal_layer_thresholds_bps.size());
1587 EXPECT_EQ(kConferenceScreencastTemporalBitrateBps,
1588 encoder_config.streams[0].temporal_layer_thresholds_bps[0]);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001589
1590 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001591}
1592
1593TEST_F(WebRtcVideoChannel2Test, DISABLED_SetSendSsrcAndCname) {
1594 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1595}
1596
1597TEST_F(WebRtcVideoChannel2Test,
1598 DISABLED_SetSendSsrcAfterCreatingReceiveChannel) {
1599 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1600}
1601
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001602TEST_F(WebRtcVideoChannel2Test, SuspendBelowMinBitrateDisabledByDefault) {
1603 FakeVideoSendStream* stream = AddSendStream();
1604 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1605}
1606
1607TEST_F(WebRtcVideoChannel2Test, SetOptionsWithSuspendBelowMinBitrate) {
1608 VideoOptions options;
1609 options.suspend_below_min_bitrate.Set(true);
1610 channel_->SetOptions(options);
1611
1612 FakeVideoSendStream* stream = AddSendStream();
1613 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
1614
1615 options.suspend_below_min_bitrate.Set(false);
1616 channel_->SetOptions(options);
1617
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001618 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001619 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1620}
1621
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001622TEST_F(WebRtcVideoChannel2Test, Vp8DenoisingEnabledByDefault) {
1623 FakeVideoSendStream* stream = AddSendStream();
1624 webrtc::VideoCodecVP8 vp8_settings;
1625 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1626 EXPECT_TRUE(vp8_settings.denoisingOn);
1627}
1628
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001629TEST_F(WebRtcVideoChannel2Test, VerifyVp8SpecificSettings) {
1630 std::vector<cricket::VideoCodec> codecs;
1631 codecs.push_back(kVp8Codec720p);
1632 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001633
Peter Boström2feafdb2015-09-09 14:32:14 +02001634 // Single-stream settings should apply with RTX as well (verifies that we
1635 // check number of regular SSRCs and not StreamParams::ssrcs which contains
1636 // both RTX and regular SSRCs).
1637 FakeVideoSendStream* stream = SetUpSimulcast(false, true);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001638
1639 cricket::FakeVideoCapturer capturer;
1640 capturer.SetScreencast(false);
1641 EXPECT_EQ(cricket::CS_RUNNING,
1642 capturer.Start(capturer.GetSupportedFormats()->front()));
1643 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1644 channel_->SetSend(true);
1645
1646 EXPECT_TRUE(capturer.CaptureFrame());
1647
1648 stream = SetDenoisingOption(false);
1649
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001650 webrtc::VideoCodecVP8 vp8_settings;
1651 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1652 EXPECT_FALSE(vp8_settings.denoisingOn);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001653 EXPECT_TRUE(vp8_settings.automaticResizeOn);
1654 EXPECT_TRUE(vp8_settings.frameDroppingOn);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001655
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001656 stream = SetDenoisingOption(true);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001657
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001658 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1659 EXPECT_TRUE(vp8_settings.denoisingOn);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001660 EXPECT_TRUE(vp8_settings.automaticResizeOn);
1661 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1662
1663 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
Peter Boström2feafdb2015-09-09 14:32:14 +02001664 stream = SetUpSimulcast(true, false);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001665 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1666 channel_->SetSend(true);
1667 EXPECT_TRUE(capturer.CaptureFrame());
1668
1669 EXPECT_EQ(3, stream->GetVideoStreams().size());
1670 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1671 // Autmatic resize off when using simulcast.
1672 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1673 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1674
1675 // In screen-share mode, denoising is forced off and simulcast disabled.
1676 capturer.SetScreencast(true);
1677 EXPECT_TRUE(capturer.CaptureFrame());
1678 stream = SetDenoisingOption(false);
1679
1680 EXPECT_EQ(1, stream->GetVideoStreams().size());
1681 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1682 EXPECT_FALSE(vp8_settings.denoisingOn);
1683 // Resizing and frame dropping always off for screen sharing.
1684 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1685 EXPECT_FALSE(vp8_settings.frameDroppingOn);
1686
1687 stream = SetDenoisingOption(true);
1688
1689 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1690 EXPECT_FALSE(vp8_settings.denoisingOn);
1691 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1692 EXPECT_FALSE(vp8_settings.frameDroppingOn);
1693
1694 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
1695}
1696
1697class Vp9SettingsTest : public WebRtcVideoChannel2Test {
1698 public:
1699 Vp9SettingsTest() : WebRtcVideoChannel2Test() {
1700 encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP9, "VP9");
1701 }
1702 virtual ~Vp9SettingsTest() {}
1703
1704 protected:
1705 void SetUp() override {
1706 engine_.SetExternalEncoderFactory(&encoder_factory_);
1707
1708 WebRtcVideoChannel2Test::SetUp();
1709 }
1710
1711 void TearDown() override {
1712 // Remove references to encoder_factory_ since this will be destroyed
1713 // before channel_ and engine_.
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001714 ASSERT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1715 }
1716
1717 cricket::FakeWebRtcVideoEncoderFactory encoder_factory_;
1718};
1719
1720TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
1721 std::vector<cricket::VideoCodec> codecs;
1722 codecs.push_back(kVp9Codec);
1723 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1724
Peter Boström2feafdb2015-09-09 14:32:14 +02001725 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
Erik SprĂ¥ng143cec12015-04-28 10:01:41 +02001726
1727 cricket::FakeVideoCapturer capturer;
1728 capturer.SetScreencast(false);
1729 EXPECT_EQ(cricket::CS_RUNNING,
1730 capturer.Start(capturer.GetSupportedFormats()->front()));
1731 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1732 channel_->SetSend(true);
1733
1734 EXPECT_TRUE(capturer.CaptureFrame());
1735
1736 stream = SetDenoisingOption(false);
1737
1738 webrtc::VideoCodecVP9 vp9_settings;
1739 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1740 EXPECT_FALSE(vp9_settings.denoisingOn);
1741 // Frame dropping always on for real time video.
1742 EXPECT_TRUE(vp9_settings.frameDroppingOn);
1743
1744 stream = SetDenoisingOption(true);
1745
1746 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1747 EXPECT_TRUE(vp9_settings.denoisingOn);
1748 EXPECT_TRUE(vp9_settings.frameDroppingOn);
1749
1750 // In screen-share mode, denoising is forced off.
1751 capturer.SetScreencast(true);
1752 EXPECT_TRUE(capturer.CaptureFrame());
1753 stream = SetDenoisingOption(false);
1754
1755 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1756 EXPECT_FALSE(vp9_settings.denoisingOn);
1757 // Frame dropping always off for screen sharing.
1758 EXPECT_FALSE(vp9_settings.frameDroppingOn);
1759
1760 stream = SetDenoisingOption(false);
1761
1762 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1763 EXPECT_FALSE(vp9_settings.denoisingOn);
1764 EXPECT_FALSE(vp9_settings.frameDroppingOn);
1765
1766 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001767}
1768
1769TEST_F(WebRtcVideoChannel2Test, DISABLED_MultipleSendStreamsWithOneCapturer) {
1770 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1771}
1772
pbos@webrtc.org8aed9452014-07-26 10:16:49 +00001773TEST_F(WebRtcVideoChannel2Test, DISABLED_SendReceiveBitratesStats) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001774 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1775}
1776
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001777TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruse) {
Erik SprĂ¥ngefbde372015-04-29 16:21:28 +02001778 TestCpuAdaptation(true, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001779}
1780
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001781TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenDisabled) {
Erik SprĂ¥ngefbde372015-04-29 16:21:28 +02001782 TestCpuAdaptation(false, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001783}
1784
Erik SprĂ¥ngefbde372015-04-29 16:21:28 +02001785TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenScreensharing) {
1786 TestCpuAdaptation(true, true);
1787}
1788
1789void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse,
1790 bool is_screenshare) {
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001791 cricket::VideoCodec codec = kVp8Codec720p;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001792 std::vector<cricket::VideoCodec> codecs;
1793 codecs.push_back(codec);
1794 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1795
Peter Boströme4328002015-04-14 22:45:29 +02001796 if (!enable_overuse) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001797 VideoOptions options;
Peter Boströme4328002015-04-14 22:45:29 +02001798 options.cpu_overuse_detection.Set(false);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001799 channel_->SetOptions(options);
1800 }
1801
1802 AddSendStream();
1803
1804 cricket::FakeVideoCapturer capturer;
Erik SprĂ¥ngefbde372015-04-29 16:21:28 +02001805 capturer.SetScreencast(is_screenshare);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001806 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1807 EXPECT_EQ(cricket::CS_RUNNING,
1808 capturer.Start(capturer.GetSupportedFormats()->front()));
1809
1810 EXPECT_TRUE(channel_->SetSend(true));
1811
1812 // Trigger overuse.
solenberge5269742015-09-08 05:13:22 -07001813 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1814 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001815 webrtc::LoadObserver* overuse_callback =
solenberge5269742015-09-08 05:13:22 -07001816 send_stream->GetConfig().overuse_callback;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001817 ASSERT_TRUE(overuse_callback != NULL);
1818 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
1819
1820 EXPECT_TRUE(capturer.CaptureFrame());
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001821 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1822
Erik SprĂ¥ngefbde372015-04-29 16:21:28 +02001823 if (enable_overuse && !is_screenshare) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001824 EXPECT_LT(send_stream->GetLastWidth(), codec.width);
1825 EXPECT_LT(send_stream->GetLastHeight(), codec.height);
1826 } else {
1827 EXPECT_EQ(codec.width, send_stream->GetLastWidth());
1828 EXPECT_EQ(codec.height, send_stream->GetLastHeight());
1829 }
1830
1831 // Trigger underuse which should go back to normal resolution.
1832 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse);
1833 EXPECT_TRUE(capturer.CaptureFrame());
1834
1835 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
1836
1837 EXPECT_EQ(codec.width, send_stream->GetLastWidth());
1838 EXPECT_EQ(codec.height, send_stream->GetLastHeight());
1839
1840 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001841}
1842
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00001843TEST_F(WebRtcVideoChannel2Test, EstimatesNtpStartTimeAndElapsedTimeCorrectly) {
1844 // Start at last timestamp to verify that wraparounds are estimated correctly.
1845 static const uint32_t kInitialTimestamp = 0xFFFFFFFFu;
1846 static const int64_t kInitialNtpTimeMs = 1247891230;
1847 static const int kFrameOffsetMs = 20;
1848 EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001849
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00001850 FakeVideoReceiveStream* stream = AddRecvStream();
1851 cricket::FakeVideoRenderer renderer;
1852 EXPECT_TRUE(channel_->SetRenderer(last_ssrc_, &renderer));
1853 EXPECT_TRUE(channel_->SetRender(true));
1854
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07001855 webrtc::VideoFrame video_frame;
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00001856 CreateBlackFrame(&video_frame, 4, 4);
1857 video_frame.set_timestamp(kInitialTimestamp);
1858 // Initial NTP time is not available on the first frame, but should still be
1859 // able to be estimated.
1860 stream->InjectFrame(video_frame, 0);
1861
1862 EXPECT_EQ(1, renderer.num_rendered_frames());
1863 EXPECT_EQ(0, renderer.last_frame_elapsed_time_ns());
1864
1865 // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which
1866 // triggers a constant-overflow warning, hence we're calculating it explicitly
1867 // here.
1868 video_frame.set_timestamp(kFrameOffsetMs * 90 - 1);
1869 video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs);
1870 stream->InjectFrame(video_frame, 0);
1871
1872 EXPECT_EQ(2, renderer.num_rendered_frames());
1873 EXPECT_EQ(kFrameOffsetMs * rtc::kNumNanosecsPerMillisec,
1874 renderer.last_frame_elapsed_time_ns());
1875
1876 // Verify that NTP time has been correctly deduced.
1877 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00001878 ASSERT_TRUE(channel_->GetStats(&info));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00001879 ASSERT_EQ(1u, info.receivers.size());
1880 EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001881}
1882
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001883TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00001884 ASSERT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001885
1886 VideoCodec codec;
1887 EXPECT_TRUE(channel_->GetSendCodec(&codec));
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00001888 EXPECT_TRUE(codec.Matches(engine_.codecs()[0]));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001889
1890 // Using a RTX setup to verify that the default RTX payload type is good.
1891 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
1892 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
1893 FakeVideoSendStream* stream = AddSendStream(
1894 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1895 webrtc::VideoSendStream::Config config = stream->GetConfig();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001896
1897 // Make sure NACK and FEC are enabled on the correct payload types.
1898 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
1899 EXPECT_EQ(default_ulpfec_codec_.id, config.rtp.fec.ulpfec_payload_type);
1900 EXPECT_EQ(default_red_codec_.id, config.rtp.fec.red_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001901
1902 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
1903 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
Shao Changbine62202f2015-04-21 20:24:50 +08001904 VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001905 // TODO(juberti): Check RTCP, PLI, TMMBR.
1906}
1907
1908TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFec) {
1909 std::vector<VideoCodec> codecs;
1910 codecs.push_back(kVp8Codec);
1911 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1912
1913 FakeVideoSendStream* stream = AddSendStream();
1914 webrtc::VideoSendStream::Config config = stream->GetConfig();
1915
1916 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type);
1917 EXPECT_EQ(-1, config.rtp.fec.red_payload_type);
1918}
1919
1920TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001921 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
1922 std::vector<VideoCodec> codecs;
1923 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
1924 codecs.push_back(rtx_codec);
1925 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1926 << "RTX codec without associated payload type should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001927}
1928
1929TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001930 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
1931 std::vector<VideoCodec> codecs;
1932 cricket::VideoCodec rtx_codec =
1933 cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id);
1934 codecs.push_back(kVp8Codec);
1935 codecs.push_back(rtx_codec);
1936 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1937
1938 cricket::VideoCodec rtx_codec2 =
1939 cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id + 1);
1940 codecs.pop_back();
1941 codecs.push_back(rtx_codec2);
1942 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1943 << "RTX without matching video codec should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001944}
1945
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001946TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFecDisablesFec) {
1947 std::vector<VideoCodec> codecs;
1948 codecs.push_back(kVp8Codec);
1949 codecs.push_back(kUlpfecCodec);
1950 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1951
1952 FakeVideoSendStream* stream = AddSendStream();
1953 webrtc::VideoSendStream::Config config = stream->GetConfig();
1954
1955 EXPECT_EQ(kUlpfecCodec.id, config.rtp.fec.ulpfec_payload_type);
1956
1957 codecs.pop_back();
1958 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001959 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001960 ASSERT_TRUE(stream != NULL);
1961 config = stream->GetConfig();
1962 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type)
1963 << "SetSendCodec without FEC should disable current FEC.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001964}
1965
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00001966TEST_F(WebRtcVideoChannel2Test, SetSendCodecsChangesExistingStreams) {
1967 std::vector<VideoCodec> codecs;
1968 codecs.push_back(kVp8Codec720p);
1969 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00001970 channel_->SetSend(true);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00001971
pbos@webrtc.org86196c42015-02-16 21:02:00 +00001972 FakeVideoSendStream* stream = AddSendStream();
1973
1974 cricket::FakeVideoCapturer capturer;
1975 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1976 EXPECT_EQ(cricket::CS_RUNNING,
1977 capturer.Start(capturer.GetSupportedFormats()->front()));
1978 EXPECT_TRUE(capturer.CaptureFrame());
1979
1980 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00001981 EXPECT_EQ(kVp8Codec720p.width, streams[0].width);
1982 EXPECT_EQ(kVp8Codec720p.height, streams[0].height);
1983
1984 codecs.clear();
1985 codecs.push_back(kVp8Codec360p);
1986 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001987 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00001988 EXPECT_EQ(kVp8Codec360p.width, streams[0].width);
1989 EXPECT_EQ(kVp8Codec360p.height, streams[0].height);
pbos@webrtc.org86196c42015-02-16 21:02:00 +00001990 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001991}
1992
pbos@webrtc.org00873182014-11-25 14:03:34 +00001993TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithBitrates) {
1994 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
1995 200000);
1996}
1997
pbos@webrtc.orga5f6fb52015-03-23 22:29:39 +00001998TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithHighMaxBitrate) {
1999 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
2000 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
2001 ASSERT_EQ(1u, streams.size());
2002 EXPECT_EQ(10000000, streams[0].max_bitrate_bps);
2003}
2004
pbos@webrtc.org00873182014-11-25 14:03:34 +00002005TEST_F(WebRtcVideoChannel2Test,
2006 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
2007 SetSendCodecsShouldWorkForBitrates(
2008 "", 0, "", -1, "", -1);
2009}
2010
2011TEST_F(WebRtcVideoChannel2Test, SetSendCodecsCapsMinAndStartBitrate) {
2012 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002013}
2014
2015TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectsMaxLessThanMinBitrate) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00002016 std::vector<VideoCodec> video_codecs = engine_.codecs();
pbos@webrtc.org88ef6322014-11-04 15:29:29 +00002017 video_codecs[0].params[kCodecParamMinBitrate] = "300";
2018 video_codecs[0].params[kCodecParamMaxBitrate] = "200";
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00002019 EXPECT_FALSE(channel_->SetSendCodecs(video_codecs));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002020}
2021
pbos@webrtc.org00873182014-11-25 14:03:34 +00002022TEST_F(WebRtcVideoChannel2Test,
2023 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
2024 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
2025 200000);
2026 channel_->SetMaxSendBandwidth(300000);
Stefan Holmere5904162015-03-26 11:11:06 +01002027 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002028 << "Setting max bitrate should keep previous min bitrate.";
Stefan Holmere5904162015-03-26 11:11:06 +01002029 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.start_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002030 << "Setting max bitrate should not reset start bitrate.";
Stefan Holmere5904162015-03-26 11:11:06 +01002031 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002032}
2033
2034TEST_F(WebRtcVideoChannel2Test, SetMaxSendBandwidthShouldBeRemovable) {
2035 channel_->SetMaxSendBandwidth(300000);
Stefan Holmere5904162015-03-26 11:11:06 +01002036 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
pbos@webrtc.org00873182014-11-25 14:03:34 +00002037 // <= 0 means disable (infinite) max bitrate.
2038 channel_->SetMaxSendBandwidth(0);
Stefan Holmere5904162015-03-26 11:11:06 +01002039 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.max_bitrate_bps)
pbos@webrtc.org00873182014-11-25 14:03:34 +00002040 << "Setting zero max bitrate did not reset start bitrate.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002041}
2042
Peter Boströmdfd53fe2015-03-27 15:58:11 +01002043TEST_F(WebRtcVideoChannel2Test, SetMaxSendBitrateCanIncreaseSenderBitrate) {
2044 std::vector<VideoCodec> codecs;
2045 codecs.push_back(kVp8Codec720p);
2046 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
2047 channel_->SetSend(true);
2048
2049 FakeVideoSendStream* stream = AddSendStream();
2050
2051 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
2052 int initial_max_bitrate_bps = streams[0].max_bitrate_bps;
2053 EXPECT_GT(initial_max_bitrate_bps, 0);
2054
2055 EXPECT_TRUE(channel_->SetMaxSendBandwidth(initial_max_bitrate_bps * 2));
2056 streams = stream->GetVideoStreams();
2057 EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps);
2058}
2059
2060TEST_F(WebRtcVideoChannel2Test,
2061 SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) {
2062 std::vector<VideoCodec> codecs;
2063 codecs.push_back(kVp8Codec720p);
2064 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
2065 channel_->SetSend(true);
2066
2067 FakeVideoSendStream* stream = AddSendStream(
2068 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
2069
2070 // Send a frame to make sure this scales up to >1 stream (simulcast).
2071 cricket::FakeVideoCapturer capturer;
2072 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &capturer));
2073 EXPECT_EQ(cricket::CS_RUNNING,
2074 capturer.Start(capturer.GetSupportedFormats()->front()));
2075 EXPECT_TRUE(capturer.CaptureFrame());
2076
2077 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
2078 ASSERT_GT(streams.size(), 1u)
2079 << "Without simulcast this test doesn't make sense.";
2080 int initial_max_bitrate_bps = 0;
2081 for (auto& video_stream : streams)
2082 initial_max_bitrate_bps += video_stream.max_bitrate_bps;
2083 EXPECT_GT(initial_max_bitrate_bps, 0);
2084
2085 EXPECT_TRUE(channel_->SetMaxSendBandwidth(initial_max_bitrate_bps * 2));
2086 streams = stream->GetVideoStreams();
2087 int increased_max_bitrate_bps = 0;
2088 for (auto& video_stream : streams)
2089 increased_max_bitrate_bps += video_stream.max_bitrate_bps;
2090 EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps);
2091
2092 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], nullptr));
2093}
2094
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002095TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMaxQuantization) {
2096 static const char* kMaxQuantization = "21";
2097 std::vector<VideoCodec> codecs;
2098 codecs.push_back(kVp8Codec);
2099 codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
2100 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00002101 EXPECT_EQ(static_cast<unsigned int>(atoi(kMaxQuantization)),
2102 AddSendStream()->GetVideoStreams().back().max_qp);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002103
2104 VideoCodec codec;
2105 EXPECT_TRUE(channel_->GetSendCodec(&codec));
2106 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
2107}
2108
2109TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadDimensions) {
2110 std::vector<cricket::VideoCodec> codecs;
2111 codecs.push_back(kVp8Codec);
2112
2113 codecs[0].width = 0;
2114 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
2115 << "Codec set though codec width is zero.";
2116
2117 codecs[0].width = kVp8Codec.width;
2118 codecs[0].height = 0;
2119 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
2120 << "Codec set though codec height is zero.";
2121}
2122
2123TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) {
2124 // TODO(pbos): Should we only allow the dynamic range?
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002125 static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002126 std::vector<cricket::VideoCodec> codecs;
2127 codecs.push_back(kVp8Codec);
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002128 for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
pkasting@chromium.orgd3245462015-02-23 21:28:22 +00002129 codecs[0].id = kIncorrectPayloads[i];
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002130 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
pkasting@chromium.orgd3245462015-02-23 21:28:22 +00002131 << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002132 }
2133}
2134
2135TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptAllValidPayloadTypes) {
2136 std::vector<cricket::VideoCodec> codecs;
2137 codecs.push_back(kVp8Codec);
2138 for (int payload_type = 0; payload_type <= 127; ++payload_type) {
2139 codecs[0].id = payload_type;
2140 EXPECT_TRUE(channel_->SetSendCodecs(codecs))
2141 << "Payload type '" << payload_type << "' rejected.";
2142 }
2143}
2144
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002145TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithOnlyVp8) {
2146 std::vector<cricket::VideoCodec> codecs;
2147 codecs.push_back(kVp8Codec);
2148 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2149}
2150
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002151// Test that we set our inbound RTX codecs properly.
2152TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithRtx) {
2153 std::vector<cricket::VideoCodec> codecs;
2154 codecs.push_back(kVp8Codec);
2155 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
2156 codecs.push_back(rtx_codec);
2157 EXPECT_FALSE(channel_->SetRecvCodecs(codecs))
2158 << "RTX codec without associated payload should be rejected.";
2159
2160 codecs[1].SetParam("apt", kVp8Codec.id + 1);
2161 EXPECT_FALSE(channel_->SetRecvCodecs(codecs))
2162 << "RTX codec with invalid associated payload type should be rejected.";
2163
2164 codecs[1].SetParam("apt", kVp8Codec.id);
2165 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2166
2167 cricket::VideoCodec rtx_codec2(97, "rtx", 0, 0, 0, 0);
2168 rtx_codec2.SetParam("apt", rtx_codec.id);
2169 codecs.push_back(rtx_codec2);
2170
2171 EXPECT_FALSE(channel_->SetRecvCodecs(codecs)) << "RTX codec with another RTX "
2172 "as associated payload type "
2173 "should be rejected.";
2174}
2175
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002176TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentPayloadType) {
2177 std::vector<cricket::VideoCodec> codecs;
2178 codecs.push_back(kVp8Codec);
2179 codecs[0].id = 99;
2180 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2181}
2182
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00002183TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsAcceptDefaultCodecs) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002184 EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00002185
2186 FakeVideoReceiveStream* stream = AddRecvStream();
2187 webrtc::VideoReceiveStream::Config config = stream->GetConfig();
pbos@webrtc.org776e6f22014-10-29 15:28:39 +00002188 EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].payload_name);
2189 EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002190}
2191
2192TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) {
2193 std::vector<VideoCodec> codecs;
2194 codecs.push_back(kVp8Codec);
2195 codecs.push_back(VideoCodec(101, "WTF3", 640, 400, 30, 0));
2196 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
2197}
2198
2199// TODO(pbos): Enable VP9 through external codec support
2200TEST_F(WebRtcVideoChannel2Test,
2201 DISABLED_SetRecvCodecsAcceptsMultipleVideoCodecs) {
2202 std::vector<VideoCodec> codecs;
2203 codecs.push_back(kVp8Codec);
2204 codecs.push_back(kVp9Codec);
2205 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2206}
2207
2208TEST_F(WebRtcVideoChannel2Test,
2209 DISABLED_SetRecvCodecsSetsFecForAllVideoCodecs) {
2210 std::vector<VideoCodec> codecs;
2211 codecs.push_back(kVp8Codec);
2212 codecs.push_back(kVp9Codec);
2213 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2214 FAIL(); // TODO(pbos): Verify that the FEC parameters are set for all codecs.
2215}
2216
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002217TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithoutFecDisablesFec) {
2218 std::vector<VideoCodec> codecs;
2219 codecs.push_back(kVp8Codec);
2220 codecs.push_back(kUlpfecCodec);
2221 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
2222
2223 FakeVideoReceiveStream* stream = AddRecvStream();
2224 webrtc::VideoReceiveStream::Config config = stream->GetConfig();
2225
2226 EXPECT_EQ(kUlpfecCodec.id, config.rtp.fec.ulpfec_payload_type);
2227
2228 codecs.pop_back();
2229 ASSERT_TRUE(channel_->SetRecvCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002230 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002231 ASSERT_TRUE(stream != NULL);
2232 config = stream->GetConfig();
2233 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type)
2234 << "SetSendCodec without FEC should disable current FEC.";
pbos@webrtc.org269605c2014-06-26 08:49:03 +00002235}
2236
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002237TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectDuplicateFecPayloads) {
2238 std::vector<VideoCodec> codecs;
2239 codecs.push_back(kVp8Codec);
2240 codecs.push_back(kRedCodec);
2241 codecs[1].id = codecs[0].id;
2242 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
2243}
2244
2245TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectDuplicateCodecPayloads) {
2246 std::vector<VideoCodec> codecs;
2247 codecs.push_back(kVp8Codec);
2248 codecs.push_back(kVp9Codec);
2249 codecs[1].id = codecs[0].id;
2250 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
2251}
2252
2253TEST_F(WebRtcVideoChannel2Test,
2254 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
2255 std::vector<VideoCodec> codecs;
2256 codecs.push_back(kVp8Codec);
2257 codecs.push_back(kVp8Codec);
2258 codecs[1].id += 1;
2259 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2260}
2261
deadbeef874ca3a2015-08-20 17:19:20 -07002262// Test that setting the same codecs but with a different order and preference
2263// doesn't result in the stream being recreated.
2264TEST_F(WebRtcVideoChannel2Test,
2265 SetRecvCodecsDifferentOrderAndPreferenceDoesntRecreateStream) {
2266 std::vector<VideoCodec> codecs1;
2267 codecs1.push_back(kVp8Codec);
2268 codecs1.push_back(kRedCodec);
2269 EXPECT_TRUE(channel_->SetRecvCodecs(codecs1));
2270
2271 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2272 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2273
2274 std::vector<VideoCodec> codecs2;
2275 codecs2.push_back(kRedCodec);
2276 codecs2.push_back(kVp8Codec);
2277 codecs2[1].preference += 1;
2278 EXPECT_TRUE(channel_->SetRecvCodecs(codecs2));
2279 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2280}
2281
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002282TEST_F(WebRtcVideoChannel2Test, SendStreamNotSendingByDefault) {
2283 EXPECT_FALSE(AddSendStream()->IsSending());
2284}
2285
pbos@webrtc.org85f42942014-07-22 09:14:58 +00002286TEST_F(WebRtcVideoChannel2Test, ReceiveStreamReceivingByDefault) {
2287 EXPECT_TRUE(AddRecvStream()->IsReceiving());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002288}
2289
2290TEST_F(WebRtcVideoChannel2Test, SetSend) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +00002291 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002292 EXPECT_FALSE(stream->IsSending());
2293
2294 // false->true
2295 EXPECT_TRUE(channel_->SetSend(true));
2296 EXPECT_TRUE(stream->IsSending());
2297 // true->true
2298 EXPECT_TRUE(channel_->SetSend(true));
2299 EXPECT_TRUE(stream->IsSending());
2300 // true->false
2301 EXPECT_TRUE(channel_->SetSend(false));
2302 EXPECT_FALSE(stream->IsSending());
2303 // false->false
2304 EXPECT_TRUE(channel_->SetSend(false));
2305 EXPECT_FALSE(stream->IsSending());
2306
2307 EXPECT_TRUE(channel_->SetSend(true));
2308 FakeVideoSendStream* new_stream = AddSendStream();
2309 EXPECT_TRUE(new_stream->IsSending())
2310 << "Send stream created after SetSend(true) not sending initially.";
2311}
2312
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00002313// This test verifies DSCP settings are properly applied on video media channel.
2314TEST_F(WebRtcVideoChannel2Test, TestSetDscpOptions) {
2315 rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
2316 new cricket::FakeNetworkInterface);
2317 channel_->SetInterface(network_interface.get());
2318 cricket::VideoOptions options;
Peter Thatchera9b4c322015-07-16 03:47:28 -07002319 EXPECT_TRUE(channel_->SetOptions(options));
2320 EXPECT_EQ(rtc::DSCP_NO_CHANGE, network_interface->dscp());
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00002321 options.dscp.Set(true);
2322 EXPECT_TRUE(channel_->SetOptions(options));
2323 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
2324 // Verify previous value is not modified if dscp option is not set.
2325 cricket::VideoOptions options1;
2326 EXPECT_TRUE(channel_->SetOptions(options1));
2327 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
2328 options.dscp.Set(false);
2329 EXPECT_TRUE(channel_->SetOptions(options));
2330 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
2331 channel_->SetInterface(NULL);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002332}
2333
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002334TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) {
Jelena Marusiccd670222015-07-16 09:30:09 +02002335 EXPECT_EQ(webrtc::kNetworkUp, fake_call_->GetNetworkState());
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002336
2337 channel_->OnReadyToSend(false);
Jelena Marusiccd670222015-07-16 09:30:09 +02002338 EXPECT_EQ(webrtc::kNetworkDown, fake_call_->GetNetworkState());
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002339
2340 channel_->OnReadyToSend(true);
Jelena Marusiccd670222015-07-16 09:30:09 +02002341 EXPECT_EQ(webrtc::kNetworkUp, fake_call_->GetNetworkState());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002342}
2343
Peter Boström74d9ed72015-03-26 16:28:31 +01002344TEST_F(WebRtcVideoChannel2Test, GetStatsReportsSentCodecName) {
2345 std::vector<cricket::VideoCodec> codecs;
2346 codecs.push_back(kVp8Codec);
2347 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2348
2349 AddSendStream();
2350
2351 cricket::VideoMediaInfo info;
2352 ASSERT_TRUE(channel_->GetStats(&info));
2353 EXPECT_EQ(kVp8Codec.name, info.senders[0].codec_name);
2354}
2355
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00002356TEST_F(WebRtcVideoChannel2Test, GetStatsReportsCpuOveruseMetrics) {
2357 FakeVideoSendStream* stream = AddSendStream();
2358 webrtc::VideoSendStream::Stats stats;
2359 stats.avg_encode_time_ms = 13;
2360 stats.encode_usage_percent = 42;
2361 stream->SetStats(stats);
2362
2363 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002364 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00002365 EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
2366 EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
2367}
2368
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002369TEST_F(WebRtcVideoChannel2Test, GetStatsReportsUpperResolution) {
2370 FakeVideoSendStream* stream = AddSendStream();
2371 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002372 stats.substreams[17].width = 123;
2373 stats.substreams[17].height = 40;
2374 stats.substreams[42].width = 80;
2375 stats.substreams[42].height = 31;
2376 stats.substreams[11].width = 20;
2377 stats.substreams[11].height = 90;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002378 stream->SetStats(stats);
2379
2380 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002381 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org273a4142014-12-01 15:23:21 +00002382 ASSERT_EQ(1u, info.senders.size());
2383 EXPECT_EQ(123, info.senders[0].send_frame_width);
2384 EXPECT_EQ(90, info.senders[0].send_frame_height);
2385}
2386
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00002387TEST_F(WebRtcVideoChannel2Test, GetStatsTracksAdaptationStats) {
2388 AddSendStream(cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
2389
2390 // Capture format VGA.
2391 cricket::FakeVideoCapturer video_capturer_vga;
2392 const std::vector<cricket::VideoFormat>* formats =
2393 video_capturer_vga.GetSupportedFormats();
2394 cricket::VideoFormat capture_format_vga = (*formats)[1];
2395 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_vga.Start(capture_format_vga));
2396 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer_vga));
2397 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
2398
2399 cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0);
2400 std::vector<cricket::VideoCodec> codecs;
2401 codecs.push_back(send_codec);
2402 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2403 EXPECT_TRUE(channel_->SetSend(true));
2404
2405 // Verify that the CpuOveruseObserver is registered and trigger downgrade.
2406 cricket::VideoOptions options;
2407 options.cpu_overuse_detection.Set(true);
2408 EXPECT_TRUE(channel_->SetOptions(options));
solenberge5269742015-09-08 05:13:22 -07002409
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00002410 // Trigger overuse.
solenberge5269742015-09-08 05:13:22 -07002411 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00002412 webrtc::LoadObserver* overuse_callback =
solenberge5269742015-09-08 05:13:22 -07002413 fake_call_->GetVideoSendStreams().front()->GetConfig().overuse_callback;
2414 ASSERT_TRUE(overuse_callback != NULL);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00002415 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
2416
2417 // Capture format VGA -> adapt (OnCpuResolutionRequest downgrade) -> VGA/2.
2418 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
2419 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002420 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00002421 ASSERT_EQ(1U, info.senders.size());
2422 EXPECT_EQ(1, info.senders[0].adapt_changes);
2423 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU,
2424 info.senders[0].adapt_reason);
2425
2426 // Trigger upgrade and verify that we adapt back up to VGA.
2427 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse);
2428 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
2429 info.Clear();
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002430 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00002431 ASSERT_EQ(1U, info.senders.size());
2432 EXPECT_EQ(2, info.senders[0].adapt_changes);
2433 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_NONE,
2434 info.senders[0].adapt_reason);
2435
2436 // No capturer (no adapter). Adapt changes from old adapter should be kept.
2437 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL));
2438 info.Clear();
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002439 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00002440 ASSERT_EQ(1U, info.senders.size());
2441 EXPECT_EQ(2, info.senders[0].adapt_changes);
2442 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_NONE,
2443 info.senders[0].adapt_reason);
2444
2445 // Set new capturer, capture format HD.
2446 cricket::FakeVideoCapturer video_capturer_hd;
2447 cricket::VideoFormat capture_format_hd = (*formats)[0];
2448 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_hd.Start(capture_format_hd));
2449 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer_hd));
2450 EXPECT_TRUE(video_capturer_hd.CaptureFrame());
2451
2452 // Trigger overuse, HD -> adapt (OnCpuResolutionRequest downgrade) -> HD/2.
2453 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
2454 EXPECT_TRUE(video_capturer_hd.CaptureFrame());
2455 info.Clear();
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002456 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00002457 ASSERT_EQ(1U, info.senders.size());
2458 EXPECT_EQ(3, info.senders[0].adapt_changes);
2459 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU,
2460 info.senders[0].adapt_reason);
2461
2462 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL));
2463}
2464
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002465TEST_F(WebRtcVideoChannel2Test,
2466 GetStatsTranslatesSendRtcpPacketTypesCorrectly) {
2467 FakeVideoSendStream* stream = AddSendStream();
2468 webrtc::VideoSendStream::Stats stats;
2469 stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2;
2470 stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3;
2471 stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4;
2472
2473 stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5;
2474 stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7;
2475 stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9;
2476
2477 stream->SetStats(stats);
2478
2479 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002480 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002481 EXPECT_EQ(7, info.senders[0].firs_rcvd);
2482 EXPECT_EQ(10, info.senders[0].nacks_rcvd);
2483 EXPECT_EQ(13, info.senders[0].plis_rcvd);
2484}
2485
2486TEST_F(WebRtcVideoChannel2Test,
2487 GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) {
2488 FakeVideoReceiveStream* stream = AddRecvStream();
2489 webrtc::VideoReceiveStream::Stats stats;
2490 stats.rtcp_packet_type_counts.fir_packets = 2;
2491 stats.rtcp_packet_type_counts.nack_packets = 3;
2492 stats.rtcp_packet_type_counts.pli_packets = 4;
2493 stream->SetStats(stats);
2494
2495 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002496 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002497 EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets,
2498 info.receivers[0].firs_sent);
2499 EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets,
2500 info.receivers[0].nacks_sent);
2501 EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets,
2502 info.receivers[0].plis_sent);
2503}
2504
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002505TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesDecodeStatsCorrectly) {
2506 FakeVideoReceiveStream* stream = AddRecvStream();
2507 webrtc::VideoReceiveStream::Stats stats;
2508 stats.decode_ms = 2;
2509 stats.max_decode_ms = 3;
2510 stats.current_delay_ms = 4;
2511 stats.target_delay_ms = 5;
2512 stats.jitter_buffer_ms = 6;
2513 stats.min_playout_delay_ms = 7;
2514 stats.render_delay_ms = 8;
2515 stream->SetStats(stats);
2516
2517 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002518 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002519 EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
2520 EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
2521 EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
2522 EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
2523 EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
2524 EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
2525 EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
2526}
2527
Peter Boström393347f2015-04-22 14:52:45 +02002528TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesReceivePacketStatsCorrectly) {
2529 FakeVideoReceiveStream* stream = AddRecvStream();
2530 webrtc::VideoReceiveStream::Stats stats;
2531 stats.rtp_stats.transmitted.payload_bytes = 2;
2532 stats.rtp_stats.transmitted.header_bytes = 3;
2533 stats.rtp_stats.transmitted.padding_bytes = 4;
2534 stats.rtp_stats.transmitted.packets = 5;
2535 stats.rtcp_stats.cumulative_lost = 6;
2536 stats.rtcp_stats.fraction_lost = 7;
2537 stream->SetStats(stats);
2538
2539 cricket::VideoMediaInfo info;
2540 ASSERT_TRUE(channel_->GetStats(&info));
2541 EXPECT_EQ(stats.rtp_stats.transmitted.payload_bytes +
2542 stats.rtp_stats.transmitted.header_bytes +
2543 stats.rtp_stats.transmitted.padding_bytes,
2544 info.receivers[0].bytes_rcvd);
2545 EXPECT_EQ(stats.rtp_stats.transmitted.packets,
2546 info.receivers[0].packets_rcvd);
2547 EXPECT_EQ(stats.rtcp_stats.cumulative_lost, info.receivers[0].packets_lost);
2548 EXPECT_EQ(static_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8),
2549 info.receivers[0].fraction_lost);
2550}
2551
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00002552TEST_F(WebRtcVideoChannel2Test, TranslatesCallStatsCorrectly) {
2553 AddSendStream();
2554 AddSendStream();
2555 webrtc::Call::Stats stats;
2556 stats.rtt_ms = 123;
2557 fake_call_->SetStats(stats);
2558
2559 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002560 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00002561 ASSERT_EQ(2u, info.senders.size());
2562 EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms);
2563 EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
2564}
2565
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00002566TEST_F(WebRtcVideoChannel2Test, TranslatesSenderBitrateStatsCorrectly) {
2567 FakeVideoSendStream* stream = AddSendStream();
2568 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002569 stats.target_media_bitrate_bps = 156;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00002570 stats.media_bitrate_bps = 123;
2571 stats.substreams[17].total_bitrate_bps = 1;
2572 stats.substreams[17].retransmit_bitrate_bps = 2;
2573 stats.substreams[42].total_bitrate_bps = 3;
2574 stats.substreams[42].retransmit_bitrate_bps = 4;
2575 stream->SetStats(stats);
2576
2577 FakeVideoSendStream* stream2 = AddSendStream();
2578 webrtc::VideoSendStream::Stats stats2;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002579 stats2.target_media_bitrate_bps = 200;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00002580 stats2.media_bitrate_bps = 321;
2581 stats2.substreams[13].total_bitrate_bps = 5;
2582 stats2.substreams[13].retransmit_bitrate_bps = 6;
2583 stats2.substreams[21].total_bitrate_bps = 7;
2584 stats2.substreams[21].retransmit_bitrate_bps = 8;
2585 stream2->SetStats(stats2);
2586
2587 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00002588 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00002589 ASSERT_EQ(2u, info.senders.size());
2590 // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
2591 // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
2592 EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate);
2593 EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate);
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002594 EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
2595 info.bw_estimations[0].target_enc_bitrate);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00002596 EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
2597 info.bw_estimations[0].actual_enc_bitrate);
2598 EXPECT_EQ(1 + 3 + 5 + 7, info.bw_estimations[0].transmit_bitrate)
2599 << "Bandwidth stats should take all streams into account.";
2600 EXPECT_EQ(2 + 4 + 6 + 8, info.bw_estimations[0].retransmit_bitrate)
2601 << "Bandwidth stats should take all streams into account.";
2602}
2603
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00002604TEST_F(WebRtcVideoChannel2Test, DefaultReceiveStreamReconfiguresToUseRtx) {
2605 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
2606
2607 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
2608 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
2609
2610 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
2611 const size_t kDataLength = 12;
2612 uint8_t data[kDataLength];
2613 memset(data, 0, sizeof(data));
2614 rtc::SetBE32(&data[8], ssrcs[0]);
2615 rtc::Buffer packet(data, kDataLength);
2616 rtc::PacketTime packet_time;
2617 channel_->OnPacketReceived(&packet, packet_time);
2618
2619 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
2620 << "No default receive stream created.";
2621 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
2622 EXPECT_EQ(0u, recv_stream->GetConfig().rtp.rtx.size())
2623 << "Default receive stream should not have configured RTX";
2624
2625 EXPECT_TRUE(channel_->AddRecvStream(
2626 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
2627 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
2628 << "AddRecvStream should've reconfigured, not added a new receiver.";
2629 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
2630 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size());
2631 EXPECT_EQ(rtx_ssrcs[0],
2632 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
2633}
2634
Peter Boströmd4362cd2015-03-25 14:17:23 +01002635TEST_F(WebRtcVideoChannel2Test, RejectsAddingStreamsWithMissingSsrcsForRtx) {
2636 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
2637
2638 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
2639 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
2640
2641 StreamParams sp =
2642 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
2643 sp.ssrcs = ssrcs; // Without RTXs, this is the important part.
2644
2645 EXPECT_FALSE(channel_->AddSendStream(sp));
2646 EXPECT_FALSE(channel_->AddRecvStream(sp));
2647}
2648
Peter Boströmd6f4c252015-03-26 16:23:04 +01002649TEST_F(WebRtcVideoChannel2Test, RejectsAddingStreamsWithOverlappingRtxSsrcs) {
2650 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
2651
2652 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
2653 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
2654
2655 StreamParams sp =
2656 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
2657
2658 EXPECT_TRUE(channel_->AddSendStream(sp));
2659 EXPECT_TRUE(channel_->AddRecvStream(sp));
2660
2661 // The RTX SSRC is already used in previous streams, using it should fail.
2662 sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]);
2663 EXPECT_FALSE(channel_->AddSendStream(sp));
2664 EXPECT_FALSE(channel_->AddRecvStream(sp));
2665
2666 // After removing the original stream this should be fine to add (makes sure
2667 // that RTX ssrcs are not forever taken).
2668 EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0]));
2669 EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0]));
2670 EXPECT_TRUE(channel_->AddSendStream(sp));
2671 EXPECT_TRUE(channel_->AddRecvStream(sp));
2672}
2673
2674TEST_F(WebRtcVideoChannel2Test,
2675 RejectsAddingStreamsWithOverlappingSimulcastSsrcs) {
2676 static const uint32 kFirstStreamSsrcs[] = {1, 2, 3};
2677 static const uint32 kOverlappingStreamSsrcs[] = {4, 3, 5};
2678 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
2679
Peter Boströmd6f4c252015-03-26 16:23:04 +01002680 StreamParams sp =
2681 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs));
2682
2683 EXPECT_TRUE(channel_->AddSendStream(sp));
2684 EXPECT_TRUE(channel_->AddRecvStream(sp));
2685
2686 // One of the SSRCs is already used in previous streams, using it should fail.
2687 sp = cricket::CreateSimStreamParams("cname",
2688 MAKE_VECTOR(kOverlappingStreamSsrcs));
2689 EXPECT_FALSE(channel_->AddSendStream(sp));
2690 EXPECT_FALSE(channel_->AddRecvStream(sp));
2691
2692 // After removing the original stream this should be fine to add (makes sure
2693 // that RTX ssrcs are not forever taken).
Peter Boström3548dd22015-05-22 18:48:36 +02002694 EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0]));
2695 EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0]));
Peter Boströmd6f4c252015-03-26 16:23:04 +01002696 EXPECT_TRUE(channel_->AddSendStream(sp));
2697 EXPECT_TRUE(channel_->AddRecvStream(sp));
2698}
2699
Peter Boström259bd202015-05-28 13:39:50 +02002700TEST_F(WebRtcVideoChannel2Test, ReportsSsrcGroupsInStats) {
2701 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
2702
2703 static const uint32_t kSenderSsrcs[] = {4, 7, 10};
2704 static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11};
2705
2706 StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams(
2707 "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs));
2708
2709 EXPECT_TRUE(channel_->AddSendStream(sender_sp));
2710
2711 static const uint32_t kReceiverSsrcs[] = {3};
2712 static const uint32_t kReceiverRtxSsrcs[] = {2};
2713
2714 StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams(
2715 "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs));
2716 EXPECT_TRUE(channel_->AddRecvStream(receiver_sp));
2717
2718 cricket::VideoMediaInfo info;
2719 ASSERT_TRUE(channel_->GetStats(&info));
2720
2721 ASSERT_EQ(1u, info.senders.size());
2722 ASSERT_EQ(1u, info.receivers.size());
2723
2724 EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups);
2725 EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups);
2726 EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
2727}
2728
pbosf42376c2015-08-28 07:35:32 -07002729TEST_F(WebRtcVideoChannel2Test, MapsReceivedPayloadTypeToCodecName) {
2730 FakeVideoReceiveStream* stream = AddRecvStream();
2731 webrtc::VideoReceiveStream::Stats stats;
2732 cricket::VideoMediaInfo info;
2733
2734 // Report no codec name before receiving.
2735 stream->SetStats(stats);
2736 ASSERT_TRUE(channel_->GetStats(&info));
2737 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
2738
2739 // Report VP8 if we're receiving it.
2740 stats.current_payload_type = kDefaultVp8PlType;
2741 stream->SetStats(stats);
2742 ASSERT_TRUE(channel_->GetStats(&info));
2743 EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());
2744
2745 // Report no codec name for unknown playload types.
2746 stats.current_payload_type = 3;
2747 stream->SetStats(stats);
2748 ASSERT_TRUE(channel_->GetStats(&info));
2749 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
2750}
2751
noahricd10a68e2015-07-10 11:27:55 -07002752void WebRtcVideoChannel2Test::TestReceiveUnsignalledSsrcPacket(
2753 uint8_t payload_type,
2754 bool expect_created_receive_stream) {
2755 std::vector<VideoCodec> codecs(engine_.codecs());
2756 // Add a RED RTX codec.
2757 VideoCodec red_rtx_codec =
2758 VideoCodec::CreateRtxCodec(kRedRtxPayloadType, kDefaultRedPlType);
2759 codecs.push_back(red_rtx_codec);
2760 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2761
2762 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
2763 const size_t kDataLength = 12;
2764 uint8_t data[kDataLength];
2765 memset(data, 0, sizeof(data));
2766
2767 rtc::Set8(data, 1, payload_type);
2768 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
2769 rtc::Buffer packet(data, kDataLength);
2770 rtc::PacketTime packet_time;
2771 channel_->OnPacketReceived(&packet, packet_time);
2772
2773 if (expect_created_receive_stream) {
2774 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
2775 << "Should have created a receive stream for payload type: "
2776 << payload_type;
2777 } else {
2778 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size())
2779 << "Shouldn't have created a receive stream for payload type: "
2780 << payload_type;
2781 }
2782}
2783
2784TEST_F(WebRtcVideoChannel2Test, Vp8PacketCreatesUnsignalledStream) {
2785 TestReceiveUnsignalledSsrcPacket(kDefaultVp8PlType, true);
2786}
2787
2788TEST_F(WebRtcVideoChannel2Test, Vp9PacketCreatesUnsignalledStream) {
2789 TestReceiveUnsignalledSsrcPacket(kDefaultVp9PlType, true);
2790}
2791
2792TEST_F(WebRtcVideoChannel2Test, RtxPacketDoesntCreateUnsignalledStream) {
2793 TestReceiveUnsignalledSsrcPacket(kDefaultRtxVp8PlType, false);
2794}
2795
2796TEST_F(WebRtcVideoChannel2Test, UlpfecPacketDoesntCreateUnsignalledStream) {
2797 TestReceiveUnsignalledSsrcPacket(kDefaultUlpfecType, false);
2798}
2799
2800TEST_F(WebRtcVideoChannel2Test, RedRtxPacketDoesntCreateUnsignalledStream) {
2801 TestReceiveUnsignalledSsrcPacket(kRedRtxPayloadType, false);
2802}
2803
Peter Boström3548dd22015-05-22 18:48:36 +02002804void WebRtcVideoChannel2Test::TestReceiverLocalSsrcConfiguration(
2805 bool receiver_first) {
2806 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
2807
2808 const uint32_t kSenderSsrc = 0xC0FFEE;
2809 const uint32_t kReceiverSsrc = 0x4711;
2810
2811 if (receiver_first) {
2812 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
2813 std::vector<FakeVideoReceiveStream*> receive_streams =
2814 fake_call_->GetVideoReceiveStreams();
2815 ASSERT_EQ(1u, receive_streams.size());
2816 // Bogus local SSRC when we have no sender.
2817 EXPECT_EQ(1, receive_streams[0]->GetConfig().rtp.local_ssrc);
2818 }
2819 AddSendStream(StreamParams::CreateLegacy(kSenderSsrc));
2820 if (!receiver_first)
2821 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
2822 std::vector<FakeVideoReceiveStream*> receive_streams =
2823 fake_call_->GetVideoReceiveStreams();
2824 ASSERT_EQ(1u, receive_streams.size());
2825 EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
2826}
2827
2828TEST_F(WebRtcVideoChannel2Test, ConfiguresLocalSsrc) {
2829 TestReceiverLocalSsrcConfiguration(false);
2830}
2831
2832TEST_F(WebRtcVideoChannel2Test, ConfiguresLocalSsrcOnExistingReceivers) {
2833 TestReceiverLocalSsrcConfiguration(true);
2834}
2835
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00002836class WebRtcVideoEngine2SimulcastTest : public testing::Test {
2837 public:
Peter Boströmd4362cd2015-03-25 14:17:23 +01002838 WebRtcVideoEngine2SimulcastTest() : engine_(nullptr) {}
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00002839
2840 protected:
2841 WebRtcVideoEngine2 engine_;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00002842};
2843
stefan658910c2015-09-03 05:48:32 -07002844// Test that if we add a stream with RTX SSRC's, SSRC's get set correctly.
2845TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_TestStreamWithRtx) {
2846 // TODO(pbos): Implement.
2847 FAIL() << "Not implemented.";
2848}
2849
2850// Test that if we get too few ssrcs are given in AddSendStream(),
2851// only supported sub-streams will be added.
2852TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_TooFewSimulcastSsrcs) {
2853 // TODO(pbos): Implement.
2854 FAIL() << "Not implemented.";
2855}
2856
2857// Test that even more than enough ssrcs are given in AddSendStream(),
2858// only supported sub-streams will be added.
2859TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_MoreThanEnoughSimulcastSscrs) {
2860 // TODO(pbos): Implement.
2861 FAIL() << "Not implemented.";
2862}
2863
2864// Test that SetSendStreamFormat works well with simulcast.
2865TEST_F(WebRtcVideoEngine2SimulcastTest,
2866 DISABLED_SetSendStreamFormatWithSimulcast) {
2867 // TODO(pbos): Implement.
2868 FAIL() << "Not implemented.";
2869}
2870
2871// Test that simulcast send codec is reset on new video frame size.
2872TEST_F(WebRtcVideoEngine2SimulcastTest,
2873 DISABLED_ResetSimulcastSendCodecOnNewFrameSize) {
2874 // TODO(pbos): Implement.
2875 FAIL() << "Not implemented.";
2876}
2877
2878// Test that simulcast send codec is reset on new portait mode video frame.
2879TEST_F(WebRtcVideoEngine2SimulcastTest,
2880 DISABLED_ResetSimulcastSendCodecOnNewPortaitFrame) {
2881 // TODO(pbos): Implement.
2882 FAIL() << "Not implemented.";
2883}
2884
2885TEST_F(WebRtcVideoEngine2SimulcastTest,
2886 DISABLED_SetBandwidthInConferenceWithSimulcast) {
2887 // TODO(pbos): Implement.
2888 FAIL() << "Not implemented.";
2889}
2890
2891// Test that sending screencast frames in conference mode changes
2892// bitrate.
2893TEST_F(WebRtcVideoEngine2SimulcastTest,
2894 DISABLED_SetBandwidthScreencastInConference) {
2895 // TODO(pbos): Implement.
2896 FAIL() << "Not implemented.";
2897}
2898
2899// Test AddSendStream with simulcast rejects bad StreamParams.
2900TEST_F(WebRtcVideoEngine2SimulcastTest,
2901 DISABLED_AddSendStreamWithBadStreamParams) {
2902 // TODO(pbos): Implement.
2903 FAIL() << "Not implemented.";
2904}
2905
2906// Test AddSendStream with simulcast sets ssrc and cname correctly.
2907TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_AddSendStreamWithSimulcast) {
2908 // TODO(pbos): Implement.
2909 FAIL() << "Not implemented.";
2910}
2911
2912// Test RemoveSendStream with simulcast.
2913TEST_F(WebRtcVideoEngine2SimulcastTest,
2914 DISABLED_RemoveSendStreamWithSimulcast) {
2915 // TODO(pbos): Implement.
2916 FAIL() << "Not implemented.";
2917}
2918
2919// Test AddSendStream after send codec has already been set will reset
2920// send codec with simulcast settings.
2921TEST_F(WebRtcVideoEngine2SimulcastTest,
2922 DISABLED_AddSimulcastStreamAfterSetSendCodec) {
2923 // TODO(pbos): Implement.
2924 FAIL() << "Not implemented.";
2925}
2926
2927TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_GetStatsWithMultipleSsrcs) {
2928 // TODO(pbos): Implement.
2929 FAIL() << "Not implemented.";
2930}
2931
2932// Test receiving channel(s) local ssrc is set to the same as the first
2933// simulcast sending ssrc.
2934TEST_F(WebRtcVideoEngine2SimulcastTest,
2935 DISABLED_AddSimulcastStreamAfterCreatingRecvChannels) {
2936 // TODO(pbos): Implement.
2937 FAIL() << "Not implemented.";
2938}
2939
2940// Test 1:1 call never turn on simulcast.
2941TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_NoSimulcastWith1on1) {
2942 // TODO(pbos): Implement.
2943 FAIL() << "Not implemented.";
2944}
2945
2946// Test SetOptions with OPT_CONFERENCE flag.
2947TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_SetOptionsWithConferenceMode) {
2948 // TODO(pbos): Implement.
2949 FAIL() << "Not implemented.";
2950}
2951
2952// Test that two different streams can have different formats.
2953TEST_F(WebRtcVideoEngine2SimulcastTest,
2954 DISABLED_MultipleSendStreamsDifferentFormats) {
2955 // TODO(pbos): Implement.
2956 FAIL() << "Not implemented.";
2957}
2958
2959TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_TestAdaptToOutputFormat) {
2960 // TODO(pbos): Implement.
2961 FAIL() << "Not implemented.";
2962}
2963
2964TEST_F(WebRtcVideoEngine2SimulcastTest,
2965 DISABLED_TestAdaptWithCpuOveruseObserver) {
2966 // TODO(pbos): Implement.
2967 FAIL() << "Not implemented.";
2968}
2969
2970// Test that codec is not reset for every frame sent in non-conference and
2971// non-screencast mode.
2972TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_DontResetCodecOnSendFrame) {
2973 // TODO(pbos): Implement.
2974 FAIL() << "Not implemented.";
2975}
2976
2977TEST_F(WebRtcVideoEngine2SimulcastTest,
2978 DISABLED_UseSimulcastAdapterOnVp8OnlyFactory) {
2979 // TODO(pbos): Implement.
2980 FAIL() << "Not implemented.";
2981}
2982
2983TEST_F(WebRtcVideoEngine2SimulcastTest,
2984 DISABLED_DontUseSimulcastAdapterOnNonVp8Factory) {
2985 // TODO(pbos): Implement.
2986 FAIL() << "Not implemented.";
2987}
2988
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00002989class WebRtcVideoChannel2SimulcastTest : public WebRtcVideoEngine2SimulcastTest,
pbos@webrtc.org86196c42015-02-16 21:02:00 +00002990 public WebRtcCallFactory {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00002991 public:
2992 WebRtcVideoChannel2SimulcastTest() : fake_call_(NULL) {}
2993
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002994 void SetUp() override {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00002995 engine_.SetCallFactory(this);
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +02002996 engine_.Init();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00002997 channel_.reset(engine_.CreateChannel(VideoOptions(), NULL));
2998 ASSERT_TRUE(fake_call_ != NULL) << "Call not created through factory.";
2999 last_ssrc_ = 123;
3000 }
3001
3002 protected:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003003 webrtc::Call* CreateCall(const webrtc::Call::Config& config) override {
Fredrik Solenbergd3ddc1b2015-05-07 17:07:34 +02003004 DCHECK(fake_call_ == NULL);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003005 fake_call_ = new FakeCall(config);
3006 return fake_call_;
3007 }
3008
3009 void VerifySimulcastSettings(const VideoCodec& codec,
3010 VideoOptions::HighestBitrate bitrate_mode,
3011 size_t num_configured_streams,
3012 size_t expected_num_streams,
3013 SimulcastBitrateMode simulcast_bitrate_mode) {
3014 cricket::VideoOptions options;
3015 options.video_highest_bitrate.Set(bitrate_mode);
3016 EXPECT_TRUE(channel_->SetOptions(options));
3017
3018 std::vector<VideoCodec> codecs;
3019 codecs.push_back(codec);
3020 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
3021
3022 std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs3);
Fredrik Solenbergd3ddc1b2015-05-07 17:07:34 +02003023 DCHECK(num_configured_streams <= ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003024 ssrcs.resize(num_configured_streams);
3025
3026 FakeVideoSendStream* stream =
3027 AddSendStream(CreateSimStreamParams("cname", ssrcs));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003028 // Send a full-size frame to trigger a stream reconfiguration to use all
3029 // expected simulcast layers.
3030 cricket::FakeVideoCapturer capturer;
3031 EXPECT_TRUE(channel_->SetCapturer(ssrcs.front(), &capturer));
3032 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(cricket::VideoFormat(
3033 codec.width, codec.height,
3034 cricket::VideoFormat::FpsToInterval(30),
3035 cricket::FOURCC_I420)));
3036 channel_->SetSend(true);
3037 EXPECT_TRUE(capturer.CaptureFrame());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003038
3039 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
3040 ASSERT_EQ(expected_num_streams, video_streams.size());
3041
3042 std::vector<webrtc::VideoStream> expected_streams = GetSimulcastConfig(
3043 num_configured_streams,
3044 simulcast_bitrate_mode,
3045 codec.width,
3046 codec.height,
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003047 0,
3048 kDefaultQpMax,
3049 codec.framerate != 0 ? codec.framerate : kDefaultFramerate);
3050
3051 ASSERT_EQ(expected_streams.size(), video_streams.size());
3052
3053 size_t num_streams = video_streams.size();
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003054 int total_max_bitrate_bps = 0;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003055 for (size_t i = 0; i < num_streams; ++i) {
3056 EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
3057 EXPECT_EQ(expected_streams[i].height, video_streams[i].height);
3058
3059 EXPECT_GT(video_streams[i].max_framerate, 0);
3060 EXPECT_EQ(expected_streams[i].max_framerate,
3061 video_streams[i].max_framerate);
3062
3063 EXPECT_GT(video_streams[i].min_bitrate_bps, 0);
3064 EXPECT_EQ(expected_streams[i].min_bitrate_bps,
3065 video_streams[i].min_bitrate_bps);
3066
3067 EXPECT_GT(video_streams[i].target_bitrate_bps, 0);
3068 EXPECT_EQ(expected_streams[i].target_bitrate_bps,
3069 video_streams[i].target_bitrate_bps);
3070
3071 EXPECT_GT(video_streams[i].max_bitrate_bps, 0);
3072 EXPECT_EQ(expected_streams[i].max_bitrate_bps,
3073 video_streams[i].max_bitrate_bps);
3074
3075 EXPECT_GT(video_streams[i].max_qp, 0);
3076 EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp);
3077
3078 EXPECT_FALSE(expected_streams[i].temporal_layer_thresholds_bps.empty());
3079 EXPECT_EQ(expected_streams[i].temporal_layer_thresholds_bps,
3080 video_streams[i].temporal_layer_thresholds_bps);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003081
3082 if (i == num_streams - 1) {
3083 total_max_bitrate_bps += video_streams[i].max_bitrate_bps;
3084 } else {
3085 total_max_bitrate_bps += video_streams[i].target_bitrate_bps;
3086 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003087 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003088 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003089 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00003090 ASSERT_EQ(1u, info.senders.size());
3091 EXPECT_EQ(total_max_bitrate_bps, info.senders[0].preferred_bitrate);
3092
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003093 EXPECT_TRUE(channel_->SetCapturer(ssrcs.front(), NULL));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003094 }
3095
3096 FakeVideoSendStream* AddSendStream() {
3097 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++));
3098 }
3099
3100 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
3101 size_t num_streams =
3102 fake_call_->GetVideoSendStreams().size();
3103 EXPECT_TRUE(channel_->AddSendStream(sp));
3104 std::vector<FakeVideoSendStream*> streams =
3105 fake_call_->GetVideoSendStreams();
3106 EXPECT_EQ(num_streams + 1, streams.size());
3107 return streams[streams.size() - 1];
3108 }
3109
3110 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
3111 return fake_call_->GetVideoSendStreams();
3112 }
3113
3114 FakeVideoReceiveStream* AddRecvStream() {
3115 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++));
3116 }
3117
3118 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
3119 size_t num_streams =
3120 fake_call_->GetVideoReceiveStreams().size();
3121 EXPECT_TRUE(channel_->AddRecvStream(sp));
3122 std::vector<FakeVideoReceiveStream*> streams =
3123 fake_call_->GetVideoReceiveStreams();
3124 EXPECT_EQ(num_streams + 1, streams.size());
3125 return streams[streams.size() - 1];
3126 }
3127
3128 FakeCall* fake_call_;
3129 rtc::scoped_ptr<VideoMediaChannel> channel_;
3130 uint32 last_ssrc_;
3131};
3132
3133TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith2SimulcastStreams) {
3134 VerifySimulcastSettings(kVp8Codec, VideoOptions::NORMAL, 2, 2, SBM_NORMAL);
3135}
3136
3137TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith3SimulcastStreams) {
3138 VerifySimulcastSettings(
3139 kVp8Codec720p, VideoOptions::NORMAL, 3, 3, SBM_NORMAL);
3140}
3141
3142TEST_F(WebRtcVideoChannel2SimulcastTest,
3143 SetSendCodecsWith2SimulcastStreamsHighBitrateMode) {
3144 VerifySimulcastSettings(kVp8Codec, VideoOptions::HIGH, 2, 2, SBM_HIGH);
3145}
3146
3147TEST_F(WebRtcVideoChannel2SimulcastTest,
3148 SetSendCodecsWith3SimulcastStreamsHighBitrateMode) {
3149 VerifySimulcastSettings(kVp8Codec720p, VideoOptions::HIGH, 3, 3, SBM_HIGH);
3150}
3151
3152TEST_F(WebRtcVideoChannel2SimulcastTest,
3153 SetSendCodecsWith2SimulcastStreamsVeryHighBitrateMode) {
3154 VerifySimulcastSettings(
3155 kVp8Codec, VideoOptions::VERY_HIGH, 2, 2, SBM_VERY_HIGH);
3156}
3157
3158TEST_F(WebRtcVideoChannel2SimulcastTest,
3159 SetSendCodecsWith3SimulcastStreamsVeryHighBitrateMode) {
3160 VerifySimulcastSettings(
3161 kVp8Codec720p, VideoOptions::VERY_HIGH, 3, 3, SBM_VERY_HIGH);
3162}
3163
3164// Test that we normalize send codec format size in simulcast.
3165TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
3166 cricket::VideoCodec codec(kVp8Codec270p);
3167 codec.width += 1;
3168 codec.height += 1;
3169 VerifySimulcastSettings(codec, VideoOptions::NORMAL, 2, 2, SBM_NORMAL);
3170}
3171
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003172TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_1280x800) {
3173 // TODO(pbos): Implement.
3174 FAIL() << "Not implemented.";
3175}
3176
3177TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_1280x720) {
3178 // TODO(pbos): Implement.
3179 FAIL() << "Not implemented.";
3180}
3181
3182TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_960x540) {
3183 // TODO(pbos): Implement.
3184 FAIL() << "Not implemented.";
3185}
3186
3187TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_960x600) {
3188 // TODO(pbos): Implement.
3189 FAIL() << "Not implemented.";
3190}
3191
3192TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_640x400) {
3193 // TODO(pbos): Implement.
3194 FAIL() << "Not implemented.";
3195}
3196
3197TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_640x360) {
3198 // TODO(pbos): Implement.
3199 FAIL() << "Not implemented.";
3200}
3201
3202TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_480x300) {
3203 // TODO(pbos): Implement.
3204 FAIL() << "Not implemented.";
3205}
3206
Peter Boström54be3e02015-05-25 15:04:24 +02003207TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_480x270) {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003208 // TODO(pbos): Implement.
3209 FAIL() << "Not implemented.";
3210}
3211
3212TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_320x200) {
3213 // TODO(pbos): Implement.
3214 FAIL() << "Not implemented.";
3215}
3216
3217TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_320x180) {
3218 // TODO(pbos): Implement.
3219 FAIL() << "Not implemented.";
3220}
3221
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00003222// Test simulcast streams are decodeable with expected sizes.
3223TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastStreams) {
3224 // TODO(pbos): Implement.
3225 FAIL() << "Not implemented.";
3226}
3227
3228// Simulcast and resolution resizing should be turned off when screencasting
3229// but not otherwise.
3230TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_ScreencastRendering) {
3231 // TODO(pbos): Implement.
3232 FAIL() << "Not implemented.";
3233}
3234
3235// Ensures that the correct settings are applied to the codec when single
3236// temporal layer screencasting is enabled, and that the correct simulcast
3237// settings are reapplied when disabling screencasting.
3238TEST_F(WebRtcVideoChannel2SimulcastTest,
3239 DISABLED_OneTemporalLayerScreencastSettings) {
3240 // TODO(pbos): Implement.
3241 FAIL() << "Not implemented.";
3242}
3243
3244// Ensures that the correct settings are applied to the codec when two temporal
3245// layer screencasting is enabled, and that the correct simulcast settings are
3246// reapplied when disabling screencasting.
3247TEST_F(WebRtcVideoChannel2SimulcastTest,
3248 DISABLED_TwoTemporalLayerScreencastSettings) {
3249 // TODO(pbos): Implement.
3250 FAIL() << "Not implemented.";
3251}
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003252
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003253} // namespace cricket