1 /*
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
28 #include <algorithm>
29 #include <map>
30 #include <vector>
31
32 #include "talk/media/base/testutils.h"
33 #include "talk/media/base/videoengine_unittest.h"
34 #include "talk/media/webrtc/fakewebrtccall.h"
35 #include "talk/media/webrtc/fakewebrtcvideoengine.h"
36 #include "talk/media/webrtc/simulcast.h"
37 #include "talk/media/webrtc/webrtcvideochannelfactory.h"
38 #include "talk/media/webrtc/webrtcvideoengine2.h"
39 #include "talk/media/webrtc/webrtcvoiceengine.h"
40 #include "webrtc/base/arraysize.h"
41 #include "webrtc/base/gunit.h"
42 #include "webrtc/base/stringutils.h"
43 #include "webrtc/test/field_trial.h"
44 #include "webrtc/video_encoder.h"
45
46 namespace {
47 static const int kDefaultQpMax = 56;
48 static const int kDefaultFramerate = 30;
49
50 static const cricket::VideoCodec kVp8Codec720p(100, "VP8", 1280, 720, 30, 0);
51 static const cricket::VideoCodec kVp8Codec360p(100, "VP8", 640, 360, 30, 0);
52 static const cricket::VideoCodec kVp8Codec270p(100, "VP8", 480, 270, 30, 0);
53
54 static const cricket::VideoCodec kVp8Codec(100, "VP8", 640, 400, 30, 0);
55 static const cricket::VideoCodec kVp9Codec(101, "VP9", 640, 400, 30, 0);
56 static const cricket::VideoCodec kH264Codec(102, "H264", 640, 400, 30, 0);
57
58 static const cricket::VideoCodec kRedCodec(116, "red", 0, 0, 0, 0);
59 static const cricket::VideoCodec kUlpfecCodec(117, "ulpfec", 0, 0, 0, 0);
60
61 static const uint8_t kRedRtxPayloadType = 125;
62
63 static const uint32_t kSsrcs1[] = {1};
64 static const uint32_t kSsrcs3[] = {1, 2, 3};
65 static const uint32_t kRtxSsrcs1[] = {4};
66 static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE;
67 static const char kUnsupportedExtensionName[] =
68 "urn:ietf:params:rtp-hdrext:unsupported";
69
VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec & codec)70 void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) {
71 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
72 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
73 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
74 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
75 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
76 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
77 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
78 cricket::kRtcpFbParamTransportCc, cricket::kParamValueEmpty)));
79 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
80 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
81 }
82
CreateBlackFrame(webrtc::VideoFrame * video_frame,int width,int height)83 static void CreateBlackFrame(webrtc::VideoFrame* video_frame,
84 int width,
85 int height) {
86 video_frame->CreateEmptyFrame(
87 width, height, width, (width + 1) / 2, (width + 1) / 2);
88 memset(video_frame->buffer(webrtc::kYPlane), 16,
89 video_frame->allocated_size(webrtc::kYPlane));
90 memset(video_frame->buffer(webrtc::kUPlane), 128,
91 video_frame->allocated_size(webrtc::kUPlane));
92 memset(video_frame->buffer(webrtc::kVPlane), 128,
93 video_frame->allocated_size(webrtc::kVPlane));
94 }
95
VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config & config,const std::map<int,int> & rtx_types)96 void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config,
97 const std::map<int, int>& rtx_types) {
98 std::map<int, int>::const_iterator it;
99 it = rtx_types.find(config.encoder_settings.payload_type);
100 EXPECT_TRUE(it != rtx_types.end() &&
101 it->second == config.rtp.rtx.payload_type);
102
103 if (config.rtp.fec.red_rtx_payload_type != -1) {
104 it = rtx_types.find(config.rtp.fec.red_payload_type);
105 EXPECT_TRUE(it != rtx_types.end() &&
106 it->second == config.rtp.fec.red_rtx_payload_type);
107 }
108 }
109 } // namespace
110
111 namespace cricket {
112 class WebRtcVideoEngine2Test : public ::testing::Test {
113 public:
WebRtcVideoEngine2Test()114 WebRtcVideoEngine2Test() : WebRtcVideoEngine2Test("") {}
WebRtcVideoEngine2Test(const char * field_trials)115 explicit WebRtcVideoEngine2Test(const char* field_trials)
116 : WebRtcVideoEngine2Test(nullptr, field_trials) {}
WebRtcVideoEngine2Test(WebRtcVoiceEngine * voice_engine,const char * field_trials)117 WebRtcVideoEngine2Test(WebRtcVoiceEngine* voice_engine,
118 const char* field_trials)
119 : override_field_trials_(field_trials),
120 call_(webrtc::Call::Create(webrtc::Call::Config())),
121 engine_() {
122 std::vector<VideoCodec> engine_codecs = engine_.codecs();
123 RTC_DCHECK(!engine_codecs.empty());
124 bool codec_set = false;
125 for (size_t i = 0; i < engine_codecs.size(); ++i) {
126 if (engine_codecs[i].name == "red") {
127 default_red_codec_ = engine_codecs[i];
128 } else if (engine_codecs[i].name == "ulpfec") {
129 default_ulpfec_codec_ = engine_codecs[i];
130 } else if (engine_codecs[i].name == "rtx") {
131 int associated_payload_type;
132 if (engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
133 &associated_payload_type)) {
134 default_apt_rtx_types_[associated_payload_type] = engine_codecs[i].id;
135 }
136 } else if (!codec_set) {
137 default_codec_ = engine_codecs[i];
138 codec_set = true;
139 }
140 }
141
142 RTC_DCHECK(codec_set);
143 }
144
145 protected:
146 VideoMediaChannel* SetUpForExternalEncoderFactory(
147 cricket::WebRtcVideoEncoderFactory* encoder_factory,
148 const std::vector<VideoCodec>& codecs);
149
150 VideoMediaChannel* SetUpForExternalDecoderFactory(
151 cricket::WebRtcVideoDecoderFactory* decoder_factory,
152 const std::vector<VideoCodec>& codecs);
153
154 webrtc::test::ScopedFieldTrials override_field_trials_;
155 // Used in WebRtcVideoEngine2VoiceTest, but defined here so it's properly
156 // initialized when the constructor is called.
157 rtc::scoped_ptr<webrtc::Call> call_;
158 WebRtcVoiceEngine voice_engine_;
159 WebRtcVideoEngine2 engine_;
160 VideoCodec default_codec_;
161 VideoCodec default_red_codec_;
162 VideoCodec default_ulpfec_codec_;
163 std::map<int, int> default_apt_rtx_types_;
164 };
165
TEST_F(WebRtcVideoEngine2Test,FindCodec)166 TEST_F(WebRtcVideoEngine2Test, FindCodec) {
167 const std::vector<cricket::VideoCodec>& c = engine_.codecs();
168 EXPECT_EQ(cricket::DefaultVideoCodecList().size(), c.size());
169
170 cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0);
171 EXPECT_TRUE(engine_.FindCodec(vp8));
172
173 cricket::VideoCodec vp8_ci(104, "vp8", 320, 200, 30, 0);
174 EXPECT_TRUE(engine_.FindCodec(vp8));
175
176 cricket::VideoCodec vp8_diff_fr_diff_pref(104, "VP8", 320, 200, 50, 50);
177 EXPECT_TRUE(engine_.FindCodec(vp8_diff_fr_diff_pref));
178
179 cricket::VideoCodec vp8_diff_id(95, "VP8", 320, 200, 30, 0);
180 EXPECT_FALSE(engine_.FindCodec(vp8_diff_id));
181 vp8_diff_id.id = 97;
182 EXPECT_TRUE(engine_.FindCodec(vp8_diff_id));
183
184 // FindCodec ignores the codec size.
185 // Test that FindCodec can accept uncommon codec size.
186 cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0);
187 EXPECT_TRUE(engine_.FindCodec(vp8_diff_res));
188
189 // PeerConnection doesn't negotiate the resolution at this point.
190 // Test that FindCodec can handle the case when width/height is 0.
191 cricket::VideoCodec vp8_zero_res(104, "VP8", 0, 0, 30, 0);
192 EXPECT_TRUE(engine_.FindCodec(vp8_zero_res));
193
194 cricket::VideoCodec red(101, "RED", 0, 0, 30, 0);
195 EXPECT_TRUE(engine_.FindCodec(red));
196
197 cricket::VideoCodec red_ci(101, "red", 0, 0, 30, 0);
198 EXPECT_TRUE(engine_.FindCodec(red));
199
200 cricket::VideoCodec fec(102, "ULPFEC", 0, 0, 30, 0);
201 EXPECT_TRUE(engine_.FindCodec(fec));
202
203 cricket::VideoCodec fec_ci(102, "ulpfec", 0, 0, 30, 0);
204 EXPECT_TRUE(engine_.FindCodec(fec));
205
206 cricket::VideoCodec rtx(96, "rtx", 0, 0, 30, 0);
207 EXPECT_TRUE(engine_.FindCodec(rtx));
208 }
209
TEST_F(WebRtcVideoEngine2Test,DefaultRtxCodecHasAssociatedPayloadTypeSet)210 TEST_F(WebRtcVideoEngine2Test, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
211 std::vector<VideoCodec> engine_codecs = engine_.codecs();
212 for (size_t i = 0; i < engine_codecs.size(); ++i) {
213 if (engine_codecs[i].name != kRtxCodecName)
214 continue;
215 int associated_payload_type;
216 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
217 &associated_payload_type));
218 EXPECT_EQ(default_codec_.id, associated_payload_type);
219 return;
220 }
221 FAIL() << "No RTX codec found among default codecs.";
222 }
223
TEST_F(WebRtcVideoEngine2Test,SupportsTimestampOffsetHeaderExtension)224 TEST_F(WebRtcVideoEngine2Test, SupportsTimestampOffsetHeaderExtension) {
225 RtpCapabilities capabilities = engine_.GetCapabilities();
226 ASSERT_FALSE(capabilities.header_extensions.empty());
227 for (const RtpHeaderExtension& extension : capabilities.header_extensions) {
228 if (extension.uri == kRtpTimestampOffsetHeaderExtension) {
229 EXPECT_EQ(kRtpTimestampOffsetHeaderExtensionDefaultId, extension.id);
230 return;
231 }
232 }
233 FAIL() << "Timestamp offset extension not in header-extension list.";
234 }
235
TEST_F(WebRtcVideoEngine2Test,SupportsAbsoluteSenderTimeHeaderExtension)236 TEST_F(WebRtcVideoEngine2Test, SupportsAbsoluteSenderTimeHeaderExtension) {
237 RtpCapabilities capabilities = engine_.GetCapabilities();
238 ASSERT_FALSE(capabilities.header_extensions.empty());
239 for (const RtpHeaderExtension& extension : capabilities.header_extensions) {
240 if (extension.uri == kRtpAbsoluteSenderTimeHeaderExtension) {
241 EXPECT_EQ(kRtpAbsoluteSenderTimeHeaderExtensionDefaultId, extension.id);
242 return;
243 }
244 }
245 FAIL() << "Absolute Sender Time extension not in header-extension list.";
246 }
247
248 class WebRtcVideoEngine2WithSendSideBweTest : public WebRtcVideoEngine2Test {
249 public:
WebRtcVideoEngine2WithSendSideBweTest()250 WebRtcVideoEngine2WithSendSideBweTest()
251 : WebRtcVideoEngine2Test("WebRTC-SendSideBwe/Enabled/") {}
252 };
253
TEST_F(WebRtcVideoEngine2WithSendSideBweTest,SupportsTransportSequenceNumberHeaderExtension)254 TEST_F(WebRtcVideoEngine2WithSendSideBweTest,
255 SupportsTransportSequenceNumberHeaderExtension) {
256 RtpCapabilities capabilities = engine_.GetCapabilities();
257 ASSERT_FALSE(capabilities.header_extensions.empty());
258 for (const RtpHeaderExtension& extension : capabilities.header_extensions) {
259 if (extension.uri == kRtpTransportSequenceNumberHeaderExtension) {
260 EXPECT_EQ(kRtpTransportSequenceNumberHeaderExtensionDefaultId,
261 extension.id);
262 return;
263 }
264 }
265 FAIL() << "Transport sequence number extension not in header-extension list.";
266 }
267
TEST_F(WebRtcVideoEngine2Test,SupportsVideoRotationHeaderExtension)268 TEST_F(WebRtcVideoEngine2Test, SupportsVideoRotationHeaderExtension) {
269 RtpCapabilities capabilities = engine_.GetCapabilities();
270 ASSERT_FALSE(capabilities.header_extensions.empty());
271 for (const RtpHeaderExtension& extension : capabilities.header_extensions) {
272 if (extension.uri == kRtpVideoRotationHeaderExtension) {
273 EXPECT_EQ(kRtpVideoRotationHeaderExtensionDefaultId, extension.id);
274 return;
275 }
276 }
277 FAIL() << "Video Rotation extension not in header-extension list.";
278 }
279
TEST_F(WebRtcVideoEngine2Test,CVOSetHeaderExtensionBeforeCapturer)280 TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionBeforeCapturer) {
281 // Allocate the capturer first to prevent early destruction before channel's
282 // dtor is called.
283 cricket::FakeVideoCapturer capturer;
284
285 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
286 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
287 cricket::VideoSendParameters parameters;
288 parameters.codecs.push_back(kVp8Codec);
289
290 rtc::scoped_ptr<VideoMediaChannel> channel(
291 SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs));
292 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
293
294 // Add CVO extension.
295 const int id = 1;
296 parameters.extensions.push_back(
297 cricket::RtpHeaderExtension(kRtpVideoRotationHeaderExtension, id));
298 EXPECT_TRUE(channel->SetSendParameters(parameters));
299
300 // Set capturer.
301 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer));
302
303 // Verify capturer has turned off applying rotation.
304 EXPECT_FALSE(capturer.GetApplyRotation());
305
306 // Verify removing header extension turns on applying rotation.
307 parameters.extensions.clear();
308 EXPECT_TRUE(channel->SetSendParameters(parameters));
309 EXPECT_TRUE(capturer.GetApplyRotation());
310 }
311
TEST_F(WebRtcVideoEngine2Test,CVOSetHeaderExtensionAfterCapturer)312 TEST_F(WebRtcVideoEngine2Test, CVOSetHeaderExtensionAfterCapturer) {
313 cricket::FakeVideoCapturer capturer;
314
315 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
316 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
317 cricket::VideoSendParameters parameters;
318 parameters.codecs.push_back(kVp8Codec);
319
320 rtc::scoped_ptr<VideoMediaChannel> channel(
321 SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs));
322 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
323
324 // Set capturer.
325 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer));
326
327 // Add CVO extension.
328 const int id = 1;
329 parameters.extensions.push_back(
330 cricket::RtpHeaderExtension(kRtpVideoRotationHeaderExtension, id));
331 EXPECT_TRUE(channel->SetSendParameters(parameters));
332
333 // Verify capturer has turned off applying rotation.
334 EXPECT_FALSE(capturer.GetApplyRotation());
335
336 // Verify removing header extension turns on applying rotation.
337 parameters.extensions.clear();
338 EXPECT_TRUE(channel->SetSendParameters(parameters));
339 EXPECT_TRUE(capturer.GetApplyRotation());
340 }
341
TEST_F(WebRtcVideoEngine2Test,SetSendFailsBeforeSettingCodecs)342 TEST_F(WebRtcVideoEngine2Test, SetSendFailsBeforeSettingCodecs) {
343 engine_.Init();
344 rtc::scoped_ptr<VideoMediaChannel> channel(
345 engine_.CreateChannel(call_.get(), cricket::VideoOptions()));
346
347 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
348
349 EXPECT_FALSE(channel->SetSend(true))
350 << "Channel should not start without codecs.";
351 EXPECT_TRUE(channel->SetSend(false))
352 << "Channel should be stoppable even without set codecs.";
353 }
354
TEST_F(WebRtcVideoEngine2Test,GetStatsWithoutSendCodecsSetDoesNotCrash)355 TEST_F(WebRtcVideoEngine2Test, GetStatsWithoutSendCodecsSetDoesNotCrash) {
356 engine_.Init();
357 rtc::scoped_ptr<VideoMediaChannel> channel(
358 engine_.CreateChannel(call_.get(), cricket::VideoOptions()));
359 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
360 VideoMediaInfo info;
361 channel->GetStats(&info);
362 }
363
TEST_F(WebRtcVideoEngine2Test,UseExternalFactoryForVp8WhenSupported)364 TEST_F(WebRtcVideoEngine2Test, UseExternalFactoryForVp8WhenSupported) {
365 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
366 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
367 cricket::VideoSendParameters parameters;
368 parameters.codecs.push_back(kVp8Codec);
369
370 rtc::scoped_ptr<VideoMediaChannel> channel(
371 SetUpForExternalEncoderFactory(&encoder_factory, parameters.codecs));
372
373 EXPECT_TRUE(
374 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
375 ASSERT_EQ(1u, encoder_factory.encoders().size());
376 EXPECT_TRUE(channel->SetSend(true));
377
378 cricket::FakeVideoCapturer capturer;
379 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer));
380 EXPECT_EQ(cricket::CS_RUNNING,
381 capturer.Start(capturer.GetSupportedFormats()->front()));
382 EXPECT_TRUE(capturer.CaptureFrame());
383 EXPECT_TRUE_WAIT(encoder_factory.encoders()[0]->GetNumEncodedFrames() > 0,
384 kTimeout);
385
386 // Sending one frame will have reallocated the encoder since input size
387 // changes from a small default to the actual frame width/height.
388 int num_created_encoders = encoder_factory.GetNumCreatedEncoders();
389 EXPECT_EQ(num_created_encoders, 2);
390
391 // Setting codecs of the same type should not reallocate any encoders
392 // (expecting a no-op).
393 EXPECT_TRUE(channel->SetSendParameters(parameters));
394 EXPECT_EQ(num_created_encoders, encoder_factory.GetNumCreatedEncoders());
395
396 // Remove stream previously added to free the external encoder instance.
397 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
398 EXPECT_EQ(0u, encoder_factory.encoders().size());
399 }
400
TEST_F(WebRtcVideoEngine2Test,CanConstructDecoderForVp9EncoderFactory)401 TEST_F(WebRtcVideoEngine2Test, CanConstructDecoderForVp9EncoderFactory) {
402 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
403 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP9, "VP9");
404 std::vector<cricket::VideoCodec> codecs;
405 codecs.push_back(kVp9Codec);
406
407 rtc::scoped_ptr<VideoMediaChannel> channel(
408 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
409
410 EXPECT_TRUE(
411 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
412 }
413
TEST_F(WebRtcVideoEngine2Test,PropagatesInputFrameTimestamp)414 TEST_F(WebRtcVideoEngine2Test, PropagatesInputFrameTimestamp) {
415 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
416 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
417 std::vector<cricket::VideoCodec> codecs;
418 codecs.push_back(kVp8Codec);
419
420 FakeCall* fake_call = new FakeCall(webrtc::Call::Config());
421 call_.reset(fake_call);
422 rtc::scoped_ptr<VideoMediaChannel> channel(
423 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
424
425 EXPECT_TRUE(
426 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
427
428 FakeVideoCapturer capturer;
429 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer));
430 capturer.Start(cricket::VideoFormat(1280, 720,
431 cricket::VideoFormat::FpsToInterval(60),
432 cricket::FOURCC_I420));
433 channel->SetSend(true);
434
435 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
436
437 EXPECT_TRUE(capturer.CaptureFrame());
438 int64_t last_timestamp = stream->GetLastTimestamp();
439 for (int i = 0; i < 10; i++) {
440 EXPECT_TRUE(capturer.CaptureFrame());
441 int64_t timestamp = stream->GetLastTimestamp();
442 int64_t interval = timestamp - last_timestamp;
443
444 // Precision changes from nanosecond to millisecond.
445 // Allow error to be no more than 1.
446 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1);
447
448 last_timestamp = timestamp;
449 }
450
451 capturer.Start(cricket::VideoFormat(1280, 720,
452 cricket::VideoFormat::FpsToInterval(30),
453 cricket::FOURCC_I420));
454
455 EXPECT_TRUE(capturer.CaptureFrame());
456 last_timestamp = stream->GetLastTimestamp();
457 for (int i = 0; i < 10; i++) {
458 EXPECT_TRUE(capturer.CaptureFrame());
459 int64_t timestamp = stream->GetLastTimestamp();
460 int64_t interval = timestamp - last_timestamp;
461
462 // Precision changes from nanosecond to millisecond.
463 // Allow error to be no more than 1.
464 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1);
465
466 last_timestamp = timestamp;
467 }
468
469 // Remove stream previously added to free the external encoder instance.
470 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
471 }
472
TEST_F(WebRtcVideoEngine2Test,ProducesIncreasingTimestampsWithResetInputSources)473 TEST_F(WebRtcVideoEngine2Test,
474 ProducesIncreasingTimestampsWithResetInputSources) {
475 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
476 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
477 std::vector<cricket::VideoCodec> codecs;
478 codecs.push_back(kVp8Codec);
479
480 FakeCall* fake_call = new FakeCall(webrtc::Call::Config());
481 call_.reset(fake_call);
482 rtc::scoped_ptr<VideoMediaChannel> channel(
483 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
484
485 EXPECT_TRUE(
486 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
487 channel->SetSend(true);
488 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
489
490 FakeVideoCapturer capturer1;
491 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer1));
492
493 cricket::CapturedFrame frame;
494 frame.width = 1280;
495 frame.height = 720;
496 frame.fourcc = cricket::FOURCC_I420;
497 frame.data_size = static_cast<uint32_t>(
498 cricket::VideoFrame::SizeOf(frame.width, frame.height));
499 rtc::scoped_ptr<char[]> data(new char[frame.data_size]);
500 frame.data = data.get();
501 memset(frame.data, 1, frame.data_size);
502 const int kInitialTimestamp = 123456;
503 frame.time_stamp = kInitialTimestamp;
504
505 // Deliver initial frame.
506 capturer1.SignalCapturedFrame(&frame);
507 // Deliver next frame 1 second later.
508 frame.time_stamp += rtc::kNumNanosecsPerSec;
509 rtc::Thread::Current()->SleepMs(1000);
510 capturer1.SignalCapturedFrame(&frame);
511
512 int64_t capturer1_last_timestamp = stream->GetLastTimestamp();
513 // Reset input source, should still be continuous even though input-frame
514 // timestamp is less than before.
515 FakeVideoCapturer capturer2;
516 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer2));
517
518 rtc::Thread::Current()->SleepMs(1);
519 // Deliver with a timestamp (10 seconds) before the previous initial one,
520 // these should not be related at all anymore and it should still work fine.
521 frame.time_stamp = kInitialTimestamp - 10000;
522 capturer2.SignalCapturedFrame(&frame);
523
524 // New timestamp should be at least 1ms in the future and not old.
525 EXPECT_GT(stream->GetLastTimestamp(), capturer1_last_timestamp);
526
527 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
528 }
529
SetUpForExternalEncoderFactory(cricket::WebRtcVideoEncoderFactory * encoder_factory,const std::vector<VideoCodec> & codecs)530 VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalEncoderFactory(
531 cricket::WebRtcVideoEncoderFactory* encoder_factory,
532 const std::vector<VideoCodec>& codecs) {
533 engine_.SetExternalEncoderFactory(encoder_factory);
534 engine_.Init();
535
536 VideoMediaChannel* channel =
537 engine_.CreateChannel(call_.get(), cricket::VideoOptions());
538 cricket::VideoSendParameters parameters;
539 parameters.codecs = codecs;
540 EXPECT_TRUE(channel->SetSendParameters(parameters));
541
542 return channel;
543 }
544
SetUpForExternalDecoderFactory(cricket::WebRtcVideoDecoderFactory * decoder_factory,const std::vector<VideoCodec> & codecs)545 VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalDecoderFactory(
546 cricket::WebRtcVideoDecoderFactory* decoder_factory,
547 const std::vector<VideoCodec>& codecs) {
548 engine_.SetExternalDecoderFactory(decoder_factory);
549 engine_.Init();
550
551 VideoMediaChannel* channel =
552 engine_.CreateChannel(call_.get(), cricket::VideoOptions());
553 cricket::VideoRecvParameters parameters;
554 parameters.codecs = codecs;
555 EXPECT_TRUE(channel->SetRecvParameters(parameters));
556
557 return channel;
558 }
559
TEST_F(WebRtcVideoEngine2Test,UsesSimulcastAdapterForVp8Factories)560 TEST_F(WebRtcVideoEngine2Test, UsesSimulcastAdapterForVp8Factories) {
561 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
562 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
563 std::vector<cricket::VideoCodec> codecs;
564 codecs.push_back(kVp8Codec);
565
566 rtc::scoped_ptr<VideoMediaChannel> channel(
567 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
568
569 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
570
571 EXPECT_TRUE(
572 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
573 EXPECT_TRUE(channel->SetSend(true));
574
575 cricket::FakeVideoCapturer capturer;
576 EXPECT_TRUE(channel->SetCapturer(ssrcs.front(), &capturer));
577 EXPECT_EQ(cricket::CS_RUNNING,
578 capturer.Start(capturer.GetSupportedFormats()->front()));
579 EXPECT_TRUE(capturer.CaptureFrame());
580
581 EXPECT_GT(encoder_factory.encoders().size(), 1u);
582
583 // Verify that encoders are configured for simulcast through adapter
584 // (increasing resolution and only configured to send one stream each).
585 int prev_width = -1;
586 for (size_t i = 0; i < encoder_factory.encoders().size(); ++i) {
587 webrtc::VideoCodec codec_settings =
588 encoder_factory.encoders()[i]->GetCodecSettings();
589 EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
590 EXPECT_GT(codec_settings.width, prev_width);
591 prev_width = codec_settings.width;
592 }
593
594 EXPECT_TRUE(channel->SetCapturer(ssrcs.front(), NULL));
595
596 channel.reset();
597 ASSERT_EQ(0u, encoder_factory.encoders().size());
598 }
599
TEST_F(WebRtcVideoEngine2Test,ChannelWithExternalH264CanChangeToInternalVp8)600 TEST_F(WebRtcVideoEngine2Test, ChannelWithExternalH264CanChangeToInternalVp8) {
601 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
602 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
603 std::vector<cricket::VideoCodec> codecs;
604 codecs.push_back(kH264Codec);
605
606 rtc::scoped_ptr<VideoMediaChannel> channel(
607 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
608
609 EXPECT_TRUE(
610 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
611 ASSERT_EQ(1u, encoder_factory.encoders().size());
612
613 cricket::VideoSendParameters parameters;
614 parameters.codecs.push_back(kVp8Codec);
615 EXPECT_TRUE(channel->SetSendParameters(parameters));
616 ASSERT_EQ(0u, encoder_factory.encoders().size());
617 }
618
TEST_F(WebRtcVideoEngine2Test,DontUseExternalEncoderFactoryForUnsupportedCodecs)619 TEST_F(WebRtcVideoEngine2Test,
620 DontUseExternalEncoderFactoryForUnsupportedCodecs) {
621 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
622 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
623 std::vector<cricket::VideoCodec> codecs;
624 codecs.push_back(kVp8Codec);
625
626 rtc::scoped_ptr<VideoMediaChannel> channel(
627 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
628
629 EXPECT_TRUE(
630 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
631 // Make sure DestroyVideoEncoder was called on the factory.
632 ASSERT_EQ(0u, encoder_factory.encoders().size());
633 }
634
TEST_F(WebRtcVideoEngine2Test,UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory)635 TEST_F(WebRtcVideoEngine2Test,
636 UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
637 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
638 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
639 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
640
641 std::vector<cricket::VideoCodec> codecs;
642 codecs.push_back(kVp8Codec);
643
644 rtc::scoped_ptr<VideoMediaChannel> channel(
645 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
646
647 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
648
649 EXPECT_TRUE(
650 channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
651 EXPECT_TRUE(channel->SetSend(true));
652
653 // Send a fake frame, or else the media engine will configure the simulcast
654 // encoder adapter at a low-enough size that it'll only create a single
655 // encoder layer.
656 cricket::FakeVideoCapturer capturer;
657 EXPECT_TRUE(channel->SetCapturer(ssrcs.front(), &capturer));
658 EXPECT_EQ(cricket::CS_RUNNING,
659 capturer.Start(capturer.GetSupportedFormats()->front()));
660 EXPECT_TRUE(capturer.CaptureFrame());
661
662 ASSERT_GT(encoder_factory.encoders().size(), 1u);
663 EXPECT_EQ(webrtc::kVideoCodecVP8,
664 encoder_factory.encoders()[0]->GetCodecSettings().codecType);
665
666 channel.reset();
667 // Make sure DestroyVideoEncoder was called on the factory.
668 EXPECT_EQ(0u, encoder_factory.encoders().size());
669 }
670
TEST_F(WebRtcVideoEngine2Test,DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory)671 TEST_F(WebRtcVideoEngine2Test,
672 DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
673 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
674 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
675 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
676
677 std::vector<cricket::VideoCodec> codecs;
678 codecs.push_back(kH264Codec);
679
680 rtc::scoped_ptr<VideoMediaChannel> channel(
681 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
682
683 EXPECT_TRUE(
684 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
685 ASSERT_EQ(1u, encoder_factory.encoders().size());
686 EXPECT_EQ(webrtc::kVideoCodecH264,
687 encoder_factory.encoders()[0]->GetCodecSettings().codecType);
688
689 channel.reset();
690 // Make sure DestroyVideoEncoder was called on the factory.
691 ASSERT_EQ(0u, encoder_factory.encoders().size());
692 }
693
TEST_F(WebRtcVideoEngine2Test,SimulcastDisabledForH264)694 TEST_F(WebRtcVideoEngine2Test, SimulcastDisabledForH264) {
695 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
696 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
697 std::vector<cricket::VideoCodec> codecs;
698 codecs.push_back(kH264Codec);
699
700 rtc::scoped_ptr<VideoMediaChannel> channel(
701 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
702
703 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
704 EXPECT_TRUE(
705 channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs)));
706 // Set the stream to 720p. This should trigger a "real" encoder
707 // initialization.
708 cricket::VideoFormat format(
709 1280, 720, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
710 EXPECT_TRUE(channel->SetSendStreamFormat(ssrcs[0], format));
711 ASSERT_EQ(1u, encoder_factory.encoders().size());
712 FakeWebRtcVideoEncoder* encoder = encoder_factory.encoders()[0];
713 EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
714 EXPECT_EQ(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
715 }
716
717 // Test external codec with be added to the end of the supported codec list.
TEST_F(WebRtcVideoEngine2Test,ReportSupportedExternalCodecs)718 TEST_F(WebRtcVideoEngine2Test, ReportSupportedExternalCodecs) {
719 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
720 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
721 engine_.SetExternalEncoderFactory(&encoder_factory);
722 engine_.Init();
723
724 std::vector<cricket::VideoCodec> codecs(engine_.codecs());
725 ASSERT_GE(codecs.size(), 2u);
726 cricket::VideoCodec internal_codec = codecs.front();
727 cricket::VideoCodec external_codec = codecs.back();
728
729 // The external codec will appear at last.
730 EXPECT_EQ("VP8", internal_codec.name);
731 EXPECT_EQ("H264", external_codec.name);
732 }
733
TEST_F(WebRtcVideoEngine2Test,RegisterExternalDecodersIfSupported)734 TEST_F(WebRtcVideoEngine2Test, RegisterExternalDecodersIfSupported) {
735 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
736 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
737 cricket::VideoRecvParameters parameters;
738 parameters.codecs.push_back(kVp8Codec);
739
740 rtc::scoped_ptr<VideoMediaChannel> channel(
741 SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs));
742
743 EXPECT_TRUE(
744 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
745 ASSERT_EQ(1u, decoder_factory.decoders().size());
746
747 // Setting codecs of the same type should not reallocate the decoder.
748 EXPECT_TRUE(channel->SetRecvParameters(parameters));
749 EXPECT_EQ(1, decoder_factory.GetNumCreatedDecoders());
750
751 // Remove stream previously added to free the external decoder instance.
752 EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
753 EXPECT_EQ(0u, decoder_factory.decoders().size());
754 }
755
756 // Verifies that we can set up decoders that are not internally supported.
TEST_F(WebRtcVideoEngine2Test,RegisterExternalH264DecoderIfSupported)757 TEST_F(WebRtcVideoEngine2Test, RegisterExternalH264DecoderIfSupported) {
758 // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We
759 // can't even query the WebRtcVideoDecoderFactory for supported codecs.
760 // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
761 // codecs.
762 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
763 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
764 engine_.SetExternalEncoderFactory(&encoder_factory);
765 cricket::FakeWebRtcVideoDecoderFactory decoder_factory;
766 decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264);
767 std::vector<cricket::VideoCodec> codecs;
768 codecs.push_back(kH264Codec);
769
770 rtc::scoped_ptr<VideoMediaChannel> channel(
771 SetUpForExternalDecoderFactory(&decoder_factory, codecs));
772
773 EXPECT_TRUE(
774 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
775 ASSERT_EQ(1u, decoder_factory.decoders().size());
776 }
777
778 class WebRtcVideoChannel2BaseTest
779 : public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> {
780 protected:
781 typedef VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> Base;
782
DefaultCodec()783 cricket::VideoCodec DefaultCodec() override { return kVp8Codec; }
784 };
785
786 #define WEBRTC_BASE_TEST(test) \
787 TEST_F(WebRtcVideoChannel2BaseTest, test) { Base::test(); }
788
789 #define WEBRTC_DISABLED_BASE_TEST(test) \
790 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_##test) { Base::test(); }
791
792 WEBRTC_BASE_TEST(SetSend);
793 WEBRTC_BASE_TEST(SetSendWithoutCodecs);
794 WEBRTC_BASE_TEST(SetSendSetsTransportBufferSizes);
795
796 WEBRTC_BASE_TEST(GetStats);
797 WEBRTC_BASE_TEST(GetStatsMultipleRecvStreams);
798 WEBRTC_BASE_TEST(GetStatsMultipleSendStreams);
799
800 WEBRTC_BASE_TEST(SetSendBandwidth);
801
802 WEBRTC_BASE_TEST(SetSendSsrc);
803 WEBRTC_BASE_TEST(SetSendSsrcAfterSetCodecs);
804
805 WEBRTC_BASE_TEST(SetRenderer);
806 WEBRTC_BASE_TEST(AddRemoveRecvStreams);
807
808 WEBRTC_DISABLED_BASE_TEST(AddRemoveRecvStreamAndRender);
809
810 WEBRTC_BASE_TEST(AddRemoveRecvStreamsNoConference);
811
812 WEBRTC_BASE_TEST(AddRemoveSendStreams);
813
814 WEBRTC_BASE_TEST(SimulateConference);
815
816 WEBRTC_BASE_TEST(AddRemoveCapturer);
817
818 WEBRTC_BASE_TEST(RemoveCapturerWithoutAdd);
819
820 WEBRTC_BASE_TEST(AddRemoveCapturerMultipleSources);
821
822 // TODO(pbos): Figure out why this fails so often.
823 WEBRTC_DISABLED_BASE_TEST(HighAspectHighHeightCapturer);
824
825 WEBRTC_BASE_TEST(RejectEmptyStreamParams);
826
827 WEBRTC_BASE_TEST(AdaptResolution16x10);
828
829 WEBRTC_BASE_TEST(AdaptResolution4x3);
830
831 // TODO(juberti): Restore this test once we support sending 0 fps.
832 WEBRTC_DISABLED_BASE_TEST(AdaptDropAllFrames);
833 // TODO(juberti): Understand why we get decode errors on this test.
834 WEBRTC_DISABLED_BASE_TEST(AdaptFramerate);
835
836 WEBRTC_BASE_TEST(SendsLowerResolutionOnSmallerFrames);
837
838 WEBRTC_BASE_TEST(MuteStream);
839
840 WEBRTC_BASE_TEST(MultipleSendStreams);
841
842 WEBRTC_BASE_TEST(SetSendStreamFormat0x0);
843
844 // TODO(zhurunz): Fix the flakey test.
845 WEBRTC_DISABLED_BASE_TEST(SetSendStreamFormat);
846
TEST_F(WebRtcVideoChannel2BaseTest,SendAndReceiveVp8Vga)847 TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Vga) {
848 SendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30, 0));
849 }
850
TEST_F(WebRtcVideoChannel2BaseTest,SendAndReceiveVp8Qvga)851 TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Qvga) {
852 SendAndReceive(cricket::VideoCodec(100, "VP8", 320, 200, 30, 0));
853 }
854
TEST_F(WebRtcVideoChannel2BaseTest,SendAndReceiveVp8SvcQqvga)855 TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8SvcQqvga) {
856 SendAndReceive(cricket::VideoCodec(100, "VP8", 160, 100, 30, 0));
857 }
858
TEST_F(WebRtcVideoChannel2BaseTest,TwoStreamsSendAndReceive)859 TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) {
860 Base::TwoStreamsSendAndReceive(kVp8Codec);
861 }
862
TEST_F(WebRtcVideoChannel2BaseTest,TwoStreamsReUseFirstStream)863 TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsReUseFirstStream) {
864 Base::TwoStreamsReUseFirstStream(kVp8Codec);
865 }
866
867 //Disabled for TSan: https://bugs.chromium.org/p/webrtc/issues/detail?id=4963
868 #if !defined(THREAD_SANITIZER)
869 WEBRTC_BASE_TEST(SendManyResizeOnce);
870 #endif // THREAD_SANITIZER
871
872 // TODO(pbos): Enable and figure out why this fails (or should work).
TEST_F(WebRtcVideoChannel2BaseTest,DISABLED_SendVp8HdAndReceiveAdaptedVp8Vga)873 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_SendVp8HdAndReceiveAdaptedVp8Vga) {
874 EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
875 EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
876 channel_->UpdateAspectRatio(1280, 720);
877 video_capturer_.reset(new cricket::FakeVideoCapturer);
878 const std::vector<cricket::VideoFormat>* formats =
879 video_capturer_->GetSupportedFormats();
880 cricket::VideoFormat capture_format_hd = (*formats)[0];
881 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format_hd));
882 EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get()));
883
884 // Capture format HD -> adapt (OnOutputFormatRequest VGA) -> VGA.
885 cricket::VideoCodec codec = kVp8Codec720p;
886 EXPECT_TRUE(SetOneCodec(codec));
887 codec.width /= 2;
888 codec.height /= 2;
889 EXPECT_TRUE(SetSend(true));
890 EXPECT_EQ(0, renderer_.num_rendered_frames());
891 EXPECT_TRUE(SendFrame());
892 EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
893 }
894
895 class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test {
896 public:
WebRtcVideoChannel2Test()897 WebRtcVideoChannel2Test() : WebRtcVideoChannel2Test("") {}
WebRtcVideoChannel2Test(const char * field_trials)898 explicit WebRtcVideoChannel2Test(const char* field_trials)
899 : WebRtcVideoEngine2Test(field_trials), last_ssrc_(0) {}
SetUp()900 void SetUp() override {
901 fake_call_.reset(new FakeCall(webrtc::Call::Config()));
902 engine_.Init();
903 channel_.reset(
904 engine_.CreateChannel(fake_call_.get(), cricket::VideoOptions()));
905 last_ssrc_ = 123;
906 send_parameters_.codecs = engine_.codecs();
907 recv_parameters_.codecs = engine_.codecs();
908 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
909 }
910
911 protected:
AddSendStream()912 FakeVideoSendStream* AddSendStream() {
913 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
914 }
915
AddSendStream(const StreamParams & sp)916 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
917 size_t num_streams = fake_call_->GetVideoSendStreams().size();
918 EXPECT_TRUE(channel_->AddSendStream(sp));
919 std::vector<FakeVideoSendStream*> streams =
920 fake_call_->GetVideoSendStreams();
921 EXPECT_EQ(num_streams + 1, streams.size());
922 return streams[streams.size() - 1];
923 }
924
GetFakeSendStreams()925 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
926 return fake_call_->GetVideoSendStreams();
927 }
928
AddRecvStream()929 FakeVideoReceiveStream* AddRecvStream() {
930 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
931 }
932
AddRecvStream(const StreamParams & sp)933 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
934 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
935 EXPECT_TRUE(channel_->AddRecvStream(sp));
936 std::vector<FakeVideoReceiveStream*> streams =
937 fake_call_->GetVideoReceiveStreams();
938 EXPECT_EQ(num_streams + 1, streams.size());
939 return streams[streams.size() - 1];
940 }
941
SetSendCodecsShouldWorkForBitrates(const char * min_bitrate_kbps,int expected_min_bitrate_bps,const char * start_bitrate_kbps,int expected_start_bitrate_bps,const char * max_bitrate_kbps,int expected_max_bitrate_bps)942 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
943 int expected_min_bitrate_bps,
944 const char* start_bitrate_kbps,
945 int expected_start_bitrate_bps,
946 const char* max_bitrate_kbps,
947 int expected_max_bitrate_bps) {
948 auto& codecs = send_parameters_.codecs;
949 codecs.clear();
950 codecs.push_back(kVp8Codec);
951 codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps;
952 codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps;
953 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps;
954 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
955
956 EXPECT_EQ(expected_min_bitrate_bps,
957 fake_call_->GetConfig().bitrate_config.min_bitrate_bps);
958 EXPECT_EQ(expected_start_bitrate_bps,
959 fake_call_->GetConfig().bitrate_config.start_bitrate_bps);
960 EXPECT_EQ(expected_max_bitrate_bps,
961 fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
962 }
963
TestSetSendRtpHeaderExtensions(const std::string & cricket_ext,const std::string & webrtc_ext)964 void TestSetSendRtpHeaderExtensions(const std::string& cricket_ext,
965 const std::string& webrtc_ext) {
966 // Enable extension.
967 const int id = 1;
968 cricket::VideoSendParameters parameters = send_parameters_;
969 parameters.extensions.push_back(
970 cricket::RtpHeaderExtension(cricket_ext, id));
971 EXPECT_TRUE(channel_->SetSendParameters(parameters));
972 FakeVideoSendStream* send_stream =
973 AddSendStream(cricket::StreamParams::CreateLegacy(123));
974
975 // Verify the send extension id.
976 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
977 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
978 EXPECT_EQ(webrtc_ext, send_stream->GetConfig().rtp.extensions[0].name);
979 // Verify call with same set of extensions returns true.
980 EXPECT_TRUE(channel_->SetSendParameters(parameters));
981 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
982 // receivers.
983 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
984 ->GetConfig()
985 .rtp.extensions.empty());
986
987 // Verify that existing RTP header extensions can be removed.
988 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
989 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
990 send_stream = fake_call_->GetVideoSendStreams()[0];
991 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
992
993 // Verify that adding receive RTP header extensions adds them for existing
994 // streams.
995 EXPECT_TRUE(channel_->SetSendParameters(parameters));
996 send_stream = fake_call_->GetVideoSendStreams()[0];
997 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
998 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
999 EXPECT_EQ(webrtc_ext, send_stream->GetConfig().rtp.extensions[0].name);
1000 }
1001
TestSetRecvRtpHeaderExtensions(const std::string & cricket_ext,const std::string & webrtc_ext)1002 void TestSetRecvRtpHeaderExtensions(const std::string& cricket_ext,
1003 const std::string& webrtc_ext) {
1004 // Enable extension.
1005 const int id = 1;
1006 cricket::VideoRecvParameters parameters = recv_parameters_;
1007 parameters.extensions.push_back(
1008 cricket::RtpHeaderExtension(cricket_ext, id));
1009 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1010
1011 FakeVideoReceiveStream* recv_stream =
1012 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1013
1014 // Verify the recv extension id.
1015 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1016 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
1017 EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name);
1018 // Verify call with same set of extensions returns true.
1019 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1020
1021 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
1022 // senders.
1023 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
1024 ->GetConfig()
1025 .rtp.extensions.empty());
1026
1027 // Verify that existing RTP header extensions can be removed.
1028 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
1029 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
1030 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1031 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
1032
1033 // Verify that adding receive RTP header extensions adds them for existing
1034 // streams.
1035 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
1036 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1037 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1038 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
1039 EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name);
1040 }
1041
TestExtensionFilter(const std::vector<std::string> & extensions,const std::string & expected_extension)1042 void TestExtensionFilter(const std::vector<std::string>& extensions,
1043 const std::string& expected_extension) {
1044 cricket::VideoSendParameters parameters = send_parameters_;
1045 int expected_id = -1;
1046 int id = 1;
1047 for (const std::string& extension : extensions) {
1048 if (extension == expected_extension)
1049 expected_id = id;
1050 parameters.extensions.push_back(
1051 cricket::RtpHeaderExtension(extension, id++));
1052 }
1053 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1054 FakeVideoSendStream* send_stream =
1055 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1056
1057 // Verify that only one of them has been set, and that it is the one with
1058 // highest priority (transport sequence number).
1059 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1060 EXPECT_EQ(expected_id, send_stream->GetConfig().rtp.extensions[0].id);
1061 EXPECT_EQ(expected_extension,
1062 send_stream->GetConfig().rtp.extensions[0].name);
1063 }
1064
1065 void TestCpuAdaptation(bool enable_overuse, bool is_screenshare);
1066 void TestReceiverLocalSsrcConfiguration(bool receiver_first);
1067 void TestReceiveUnsignalledSsrcPacket(uint8_t payload_type,
1068 bool expect_created_receive_stream);
1069
SetDenoisingOption(const cricket::VideoSendParameters & parameters,bool enabled)1070 FakeVideoSendStream* SetDenoisingOption(
1071 const cricket::VideoSendParameters& parameters, bool enabled) {
1072 cricket::VideoSendParameters params = parameters;
1073 params.options.video_noise_reduction = rtc::Optional<bool>(enabled);
1074 channel_->SetSendParameters(params);
1075 return fake_call_->GetVideoSendStreams().back();
1076 }
1077
SetUpSimulcast(bool enabled,bool with_rtx)1078 FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) {
1079 const int kRtxSsrcOffset = 0xDEADBEEF;
1080 last_ssrc_ += 3;
1081 std::vector<uint32_t> ssrcs;
1082 std::vector<uint32_t> rtx_ssrcs;
1083 uint32_t num_streams = enabled ? 3 : 1;
1084 for (uint32_t i = 0; i < num_streams; ++i) {
1085 uint32_t ssrc = last_ssrc_ + i;
1086 ssrcs.push_back(ssrc);
1087 if (with_rtx) {
1088 rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset);
1089 }
1090 }
1091 if (with_rtx) {
1092 return AddSendStream(
1093 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1094 }
1095 return AddSendStream(CreateSimStreamParams("cname", ssrcs));
1096 }
1097
1098 rtc::scoped_ptr<FakeCall> fake_call_;
1099 rtc::scoped_ptr<VideoMediaChannel> channel_;
1100 cricket::VideoSendParameters send_parameters_;
1101 cricket::VideoRecvParameters recv_parameters_;
1102 uint32_t last_ssrc_;
1103 };
1104
TEST_F(WebRtcVideoChannel2Test,SetsSyncGroupFromSyncLabel)1105 TEST_F(WebRtcVideoChannel2Test, SetsSyncGroupFromSyncLabel) {
1106 const uint32_t kVideoSsrc = 123;
1107 const std::string kSyncLabel = "AvSyncLabel";
1108
1109 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc);
1110 sp.sync_label = kSyncLabel;
1111 EXPECT_TRUE(channel_->AddRecvStream(sp));
1112
1113 EXPECT_EQ(1, fake_call_->GetVideoReceiveStreams().size());
1114 EXPECT_EQ(kSyncLabel,
1115 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group)
1116 << "SyncGroup should be set based on sync_label";
1117 }
1118
TEST_F(WebRtcVideoChannel2Test,RecvStreamWithSimAndRtx)1119 TEST_F(WebRtcVideoChannel2Test, RecvStreamWithSimAndRtx) {
1120 cricket::VideoSendParameters parameters;
1121 parameters.codecs = engine_.codecs();
1122 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1123 EXPECT_TRUE(channel_->SetSend(true));
1124 parameters.options.conference_mode = rtc::Optional<bool>(true);
1125 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1126
1127 // Send side.
1128 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
1129 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
1130 FakeVideoSendStream* send_stream = AddSendStream(
1131 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1132
1133 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
1134 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
1135 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
1136
1137 // Receiver side.
1138 FakeVideoReceiveStream* recv_stream = AddRecvStream(
1139 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1140 ASSERT_GT(recv_stream->GetConfig().rtp.rtx.size(), 0u)
1141 << "No SSRCs for RTX configured by AddRecvStream.";
1142 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size())
1143 << "This test only works with one receive codec. Please update the test.";
1144 EXPECT_EQ(rtx_ssrcs[0],
1145 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
1146 // TODO(pbos): Make sure we set the RTX for correct payloads etc.
1147 }
1148
TEST_F(WebRtcVideoChannel2Test,RecvStreamWithRtx)1149 TEST_F(WebRtcVideoChannel2Test, RecvStreamWithRtx) {
1150 // Setup one channel with an associated RTX stream.
1151 cricket::StreamParams params =
1152 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
1153 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
1154 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
1155 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size());
1156 EXPECT_EQ(kRtxSsrcs1[0],
1157 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
1158 }
1159
TEST_F(WebRtcVideoChannel2Test,RecvStreamNoRtx)1160 TEST_F(WebRtcVideoChannel2Test, RecvStreamNoRtx) {
1161 // Setup one channel without an associated RTX stream.
1162 cricket::StreamParams params =
1163 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
1164 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
1165 ASSERT_TRUE(recv_stream->GetConfig().rtp.rtx.empty());
1166 }
1167
TEST_F(WebRtcVideoChannel2Test,NoHeaderExtesionsByDefault)1168 TEST_F(WebRtcVideoChannel2Test, NoHeaderExtesionsByDefault) {
1169 FakeVideoSendStream* send_stream =
1170 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
1171 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
1172
1173 FakeVideoReceiveStream* recv_stream =
1174 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
1175 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
1176 }
1177
1178 // Test support for RTP timestamp offset header extension.
TEST_F(WebRtcVideoChannel2Test,SendRtpTimestampOffsetHeaderExtensions)1179 TEST_F(WebRtcVideoChannel2Test, SendRtpTimestampOffsetHeaderExtensions) {
1180 TestSetSendRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension,
1181 webrtc::RtpExtension::kTOffset);
1182 }
TEST_F(WebRtcVideoChannel2Test,RecvRtpTimestampOffsetHeaderExtensions)1183 TEST_F(WebRtcVideoChannel2Test, RecvRtpTimestampOffsetHeaderExtensions) {
1184 TestSetRecvRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension,
1185 webrtc::RtpExtension::kTOffset);
1186 }
1187
1188 // Test support for absolute send time header extension.
TEST_F(WebRtcVideoChannel2Test,SendAbsoluteSendTimeHeaderExtensions)1189 TEST_F(WebRtcVideoChannel2Test, SendAbsoluteSendTimeHeaderExtensions) {
1190 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension,
1191 webrtc::RtpExtension::kAbsSendTime);
1192 }
TEST_F(WebRtcVideoChannel2Test,RecvAbsoluteSendTimeHeaderExtensions)1193 TEST_F(WebRtcVideoChannel2Test, RecvAbsoluteSendTimeHeaderExtensions) {
1194 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension,
1195 webrtc::RtpExtension::kAbsSendTime);
1196 }
1197
TEST_F(WebRtcVideoChannel2Test,FiltersExtensionsPicksTransportSeqNum)1198 TEST_F(WebRtcVideoChannel2Test, FiltersExtensionsPicksTransportSeqNum) {
1199 // Enable three redundant extensions.
1200 std::vector<std::string> extensions;
1201 extensions.push_back(kRtpAbsoluteSenderTimeHeaderExtension);
1202 extensions.push_back(kRtpTimestampOffsetHeaderExtension);
1203 extensions.push_back(kRtpTransportSequenceNumberHeaderExtension);
1204 TestExtensionFilter(extensions, kRtpTransportSequenceNumberHeaderExtension);
1205 }
1206
TEST_F(WebRtcVideoChannel2Test,FiltersExtensionsPicksAbsSendTime)1207 TEST_F(WebRtcVideoChannel2Test, FiltersExtensionsPicksAbsSendTime) {
1208 // Enable two redundant extensions.
1209 std::vector<std::string> extensions;
1210 extensions.push_back(kRtpAbsoluteSenderTimeHeaderExtension);
1211 extensions.push_back(kRtpTimestampOffsetHeaderExtension);
1212 TestExtensionFilter(extensions, kRtpAbsoluteSenderTimeHeaderExtension);
1213 }
1214
1215 class WebRtcVideoChannel2WithSendSideBweTest : public WebRtcVideoChannel2Test {
1216 public:
WebRtcVideoChannel2WithSendSideBweTest()1217 WebRtcVideoChannel2WithSendSideBweTest()
1218 : WebRtcVideoChannel2Test("WebRTC-SendSideBwe/Enabled/") {}
1219 };
1220
1221 // Test support for transport sequence number header extension.
TEST_F(WebRtcVideoChannel2WithSendSideBweTest,SendTransportSequenceNumberHeaderExtensions)1222 TEST_F(WebRtcVideoChannel2WithSendSideBweTest,
1223 SendTransportSequenceNumberHeaderExtensions) {
1224 TestSetSendRtpHeaderExtensions(
1225 kRtpTransportSequenceNumberHeaderExtension,
1226 webrtc::RtpExtension::kTransportSequenceNumber);
1227 }
TEST_F(WebRtcVideoChannel2WithSendSideBweTest,RecvTransportSequenceNumberHeaderExtensions)1228 TEST_F(WebRtcVideoChannel2WithSendSideBweTest,
1229 RecvTransportSequenceNumberHeaderExtensions) {
1230 TestSetRecvRtpHeaderExtensions(
1231 kRtpTransportSequenceNumberHeaderExtension,
1232 webrtc::RtpExtension::kTransportSequenceNumber);
1233 }
1234
1235 // Test support for video rotation header extension.
TEST_F(WebRtcVideoChannel2Test,SendVideoRotationHeaderExtensions)1236 TEST_F(WebRtcVideoChannel2Test, SendVideoRotationHeaderExtensions) {
1237 TestSetSendRtpHeaderExtensions(kRtpVideoRotationHeaderExtension,
1238 webrtc::RtpExtension::kVideoRotation);
1239 }
TEST_F(WebRtcVideoChannel2Test,RecvVideoRotationHeaderExtensions)1240 TEST_F(WebRtcVideoChannel2Test, RecvVideoRotationHeaderExtensions) {
1241 TestSetRecvRtpHeaderExtensions(kRtpVideoRotationHeaderExtension,
1242 webrtc::RtpExtension::kVideoRotation);
1243 }
1244
TEST_F(WebRtcVideoChannel2Test,IdenticalSendExtensionsDoesntRecreateStream)1245 TEST_F(WebRtcVideoChannel2Test, IdenticalSendExtensionsDoesntRecreateStream) {
1246 const int kAbsSendTimeId = 1;
1247 const int kVideoRotationId = 2;
1248 send_parameters_.extensions.push_back(cricket::RtpHeaderExtension(
1249 kRtpAbsoluteSenderTimeHeaderExtension, kAbsSendTimeId));
1250 send_parameters_.extensions.push_back(cricket::RtpHeaderExtension(
1251 kRtpVideoRotationHeaderExtension, kVideoRotationId));
1252
1253 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
1254 FakeVideoSendStream* send_stream =
1255 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1256
1257 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1258 ASSERT_EQ(2u, send_stream->GetConfig().rtp.extensions.size());
1259
1260 // Setting the same extensions (even if in different order) shouldn't
1261 // reallocate the stream.
1262 std::reverse(send_parameters_.extensions.begin(),
1263 send_parameters_.extensions.end());
1264 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
1265
1266 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
1267
1268 // Setting different extensions should recreate the stream.
1269 send_parameters_.extensions.resize(1);
1270 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
1271
1272 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
1273 }
1274
TEST_F(WebRtcVideoChannel2Test,IdenticalRecvExtensionsDoesntRecreateStream)1275 TEST_F(WebRtcVideoChannel2Test, IdenticalRecvExtensionsDoesntRecreateStream) {
1276 const int kTOffsetId = 1;
1277 const int kAbsSendTimeId = 2;
1278 const int kVideoRotationId = 3;
1279 recv_parameters_.extensions.push_back(cricket::RtpHeaderExtension(
1280 kRtpAbsoluteSenderTimeHeaderExtension, kAbsSendTimeId));
1281 recv_parameters_.extensions.push_back(cricket::RtpHeaderExtension(
1282 kRtpTimestampOffsetHeaderExtension, kTOffsetId));
1283 recv_parameters_.extensions.push_back(cricket::RtpHeaderExtension(
1284 kRtpVideoRotationHeaderExtension, kVideoRotationId));
1285
1286 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
1287 FakeVideoReceiveStream* recv_stream =
1288 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1289
1290 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
1291 ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size());
1292
1293 // Setting the same extensions (even if in different order) shouldn't
1294 // reallocate the stream.
1295 std::reverse(recv_parameters_.extensions.begin(),
1296 recv_parameters_.extensions.end());
1297 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
1298
1299 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
1300
1301 // Setting different extensions should recreate the stream.
1302 recv_parameters_.extensions.resize(1);
1303 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
1304
1305 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
1306 }
1307
TEST_F(WebRtcVideoChannel2Test,SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions)1308 TEST_F(WebRtcVideoChannel2Test,
1309 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
1310 const int kUnsupportedId = 1;
1311 const int kTOffsetId = 2;
1312
1313 send_parameters_.extensions.push_back(
1314 cricket::RtpHeaderExtension(kUnsupportedExtensionName, kUnsupportedId));
1315 send_parameters_.extensions.push_back(
1316 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, kTOffsetId));
1317 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
1318 FakeVideoSendStream* send_stream =
1319 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1320
1321 // Only timestamp offset extension is set to send stream,
1322 // unsupported rtp extension is ignored.
1323 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1324 EXPECT_STREQ(webrtc::RtpExtension::kTOffset,
1325 send_stream->GetConfig().rtp.extensions[0].name.c_str());
1326 }
1327
TEST_F(WebRtcVideoChannel2Test,SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions)1328 TEST_F(WebRtcVideoChannel2Test,
1329 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
1330 const int kUnsupportedId = 1;
1331 const int kTOffsetId = 2;
1332
1333 recv_parameters_.extensions.push_back(
1334 cricket::RtpHeaderExtension(kUnsupportedExtensionName, kUnsupportedId));
1335 recv_parameters_.extensions.push_back(
1336 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, kTOffsetId));
1337 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
1338 FakeVideoReceiveStream* recv_stream =
1339 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1340
1341 // Only timestamp offset extension is set to receive stream,
1342 // unsupported rtp extension is ignored.
1343 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1344 EXPECT_STREQ(webrtc::RtpExtension::kTOffset,
1345 recv_stream->GetConfig().rtp.extensions[0].name.c_str());
1346 }
1347
TEST_F(WebRtcVideoChannel2Test,SetSendRtpHeaderExtensionsRejectsIncorrectIds)1348 TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
1349 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
1350 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
1351 send_parameters_.extensions.push_back(cricket::RtpHeaderExtension(
1352 webrtc::RtpExtension::kTOffset, kIncorrectIds[i]));
1353 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_))
1354 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1355 }
1356 }
1357
TEST_F(WebRtcVideoChannel2Test,SetRecvRtpHeaderExtensionsRejectsIncorrectIds)1358 TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
1359 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
1360 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
1361 recv_parameters_.extensions.push_back(cricket::RtpHeaderExtension(
1362 webrtc::RtpExtension::kTOffset, kIncorrectIds[i]));
1363 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_))
1364 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1365 }
1366 }
1367
TEST_F(WebRtcVideoChannel2Test,SetSendRtpHeaderExtensionsRejectsDuplicateIds)1368 TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
1369 const int id = 1;
1370 send_parameters_.extensions.push_back(
1371 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
1372 send_parameters_.extensions.push_back(
1373 cricket::RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, id));
1374 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
1375
1376 // Duplicate entries are also not supported.
1377 send_parameters_.extensions.clear();
1378 send_parameters_.extensions.push_back(
1379 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
1380 send_parameters_.extensions.push_back(send_parameters_.extensions.back());
1381 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
1382 }
1383
TEST_F(WebRtcVideoChannel2Test,SetRecvRtpHeaderExtensionsRejectsDuplicateIds)1384 TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
1385 const int id = 1;
1386 recv_parameters_.extensions.push_back(
1387 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
1388 recv_parameters_.extensions.push_back(
1389 cricket::RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, id));
1390 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
1391
1392 // Duplicate entries are also not supported.
1393 recv_parameters_.extensions.clear();
1394 recv_parameters_.extensions.push_back(
1395 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
1396 recv_parameters_.extensions.push_back(recv_parameters_.extensions.back());
1397 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
1398 }
1399
TEST_F(WebRtcVideoChannel2Test,DISABLED_LeakyBucketTest)1400 TEST_F(WebRtcVideoChannel2Test, DISABLED_LeakyBucketTest) {
1401 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1402 }
1403
TEST_F(WebRtcVideoChannel2Test,DISABLED_BufferedModeLatency)1404 TEST_F(WebRtcVideoChannel2Test, DISABLED_BufferedModeLatency) {
1405 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1406 }
1407
TEST_F(WebRtcVideoChannel2Test,DISABLED_AdditiveVideoOptions)1408 TEST_F(WebRtcVideoChannel2Test, DISABLED_AdditiveVideoOptions) {
1409 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1410 }
1411
TEST_F(WebRtcVideoChannel2Test,AddRecvStreamOnlyUsesOneReceiveStream)1412 TEST_F(WebRtcVideoChannel2Test, AddRecvStreamOnlyUsesOneReceiveStream) {
1413 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1414 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
1415 }
1416
TEST_F(WebRtcVideoChannel2Test,RtcpIsCompoundByDefault)1417 TEST_F(WebRtcVideoChannel2Test, RtcpIsCompoundByDefault) {
1418 FakeVideoReceiveStream* stream = AddRecvStream();
1419 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream->GetConfig().rtp.rtcp_mode);
1420 }
1421
TEST_F(WebRtcVideoChannel2Test,RembIsEnabledByDefault)1422 TEST_F(WebRtcVideoChannel2Test, RembIsEnabledByDefault) {
1423 FakeVideoReceiveStream* stream = AddRecvStream();
1424 EXPECT_TRUE(stream->GetConfig().rtp.remb);
1425 }
1426
TEST_F(WebRtcVideoChannel2Test,TransportCcIsEnabledByDefault)1427 TEST_F(WebRtcVideoChannel2Test, TransportCcIsEnabledByDefault) {
1428 FakeVideoReceiveStream* stream = AddRecvStream();
1429 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1430 }
1431
TEST_F(WebRtcVideoChannel2Test,RembCanBeEnabledAndDisabled)1432 TEST_F(WebRtcVideoChannel2Test, RembCanBeEnabledAndDisabled) {
1433 FakeVideoReceiveStream* stream = AddRecvStream();
1434 EXPECT_TRUE(stream->GetConfig().rtp.remb);
1435
1436 // Verify that REMB is turned off when send(!) codecs without REMB are set.
1437 cricket::VideoSendParameters parameters;
1438 parameters.codecs.push_back(kVp8Codec);
1439 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1440 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1441 stream = fake_call_->GetVideoReceiveStreams()[0];
1442 EXPECT_FALSE(stream->GetConfig().rtp.remb);
1443
1444 // Verify that REMB is turned on when setting default codecs since the
1445 // default codecs have REMB enabled.
1446 parameters.codecs = engine_.codecs();
1447 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1448 stream = fake_call_->GetVideoReceiveStreams()[0];
1449 EXPECT_TRUE(stream->GetConfig().rtp.remb);
1450 }
1451
TEST_F(WebRtcVideoChannel2Test,TransportCcCanBeEnabledAndDisabled)1452 TEST_F(WebRtcVideoChannel2Test, TransportCcCanBeEnabledAndDisabled) {
1453 FakeVideoReceiveStream* stream = AddRecvStream();
1454 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1455
1456 // Verify that transport cc feedback is turned off when send(!) codecs without
1457 // transport cc feedback are set.
1458 cricket::VideoSendParameters parameters;
1459 parameters.codecs.push_back(kVp8Codec);
1460 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1461 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1462 stream = fake_call_->GetVideoReceiveStreams()[0];
1463 EXPECT_FALSE(stream->GetConfig().rtp.transport_cc);
1464
1465 // Verify that transport cc feedback is turned on when setting default codecs
1466 // since the default codecs have transport cc feedback enabled.
1467 parameters.codecs = engine_.codecs();
1468 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1469 stream = fake_call_->GetVideoReceiveStreams()[0];
1470 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
1471 }
1472
TEST_F(WebRtcVideoChannel2Test,NackIsEnabledByDefault)1473 TEST_F(WebRtcVideoChannel2Test, NackIsEnabledByDefault) {
1474 VerifyCodecHasDefaultFeedbackParams(default_codec_);
1475
1476 cricket::VideoSendParameters parameters;
1477 parameters.codecs = engine_.codecs();
1478 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1479 EXPECT_TRUE(channel_->SetSend(true));
1480
1481 // Send side.
1482 FakeVideoSendStream* send_stream =
1483 AddSendStream(cricket::StreamParams::CreateLegacy(1));
1484 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1485
1486 // Receiver side.
1487 FakeVideoReceiveStream* recv_stream =
1488 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
1489 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1490
1491 // Nack history size should match between sender and receiver.
1492 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
1493 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
1494 }
1495
TEST_F(WebRtcVideoChannel2Test,NackCanBeEnabledAndDisabled)1496 TEST_F(WebRtcVideoChannel2Test, NackCanBeEnabledAndDisabled) {
1497 FakeVideoSendStream* send_stream = AddSendStream();
1498 FakeVideoReceiveStream* recv_stream = AddRecvStream();
1499
1500 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1501 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1502
1503 // Verify that NACK is turned off when send(!) codecs without NACK are set.
1504 cricket::VideoSendParameters parameters;
1505 parameters.codecs.push_back(kVp8Codec);
1506 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
1507 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1508 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1509 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
1510 send_stream = fake_call_->GetVideoSendStreams()[0];
1511 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
1512
1513 // Verify that NACK is turned on when setting default codecs since the
1514 // default codecs have NACK enabled.
1515 parameters.codecs = engine_.codecs();
1516 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1517 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
1518 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1519 send_stream = fake_call_->GetVideoSendStreams()[0];
1520 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1521 }
1522
TEST_F(WebRtcVideoChannel2Test,DISABLED_VideoProtectionInterop)1523 TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInterop) {
1524 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1525 }
1526
TEST_F(WebRtcVideoChannel2Test,DISABLED_VideoProtectionInteropReversed)1527 TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInteropReversed) {
1528 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1529 }
1530
TEST_F(WebRtcVideoChannel2Test,DISABLED_HybridNackFecConference)1531 TEST_F(WebRtcVideoChannel2Test, DISABLED_HybridNackFecConference) {
1532 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1533 }
1534
TEST_F(WebRtcVideoChannel2Test,DISABLED_AddRemoveRecvStreamConference)1535 TEST_F(WebRtcVideoChannel2Test, DISABLED_AddRemoveRecvStreamConference) {
1536 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1537 }
1538
TEST_F(WebRtcVideoChannel2Test,DISABLED_SetBandwidthAuto)1539 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAuto) {
1540 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1541 }
1542
TEST_F(WebRtcVideoChannel2Test,DISABLED_SetBandwidthAutoCapped)1543 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAutoCapped) {
1544 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1545 }
1546
TEST_F(WebRtcVideoChannel2Test,DISABLED_SetBandwidthFixed)1547 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthFixed) {
1548 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1549 }
1550
TEST_F(WebRtcVideoChannel2Test,DISABLED_SetBandwidthInConference)1551 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthInConference) {
1552 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1553 }
1554
TEST_F(WebRtcVideoChannel2Test,UsesCorrectSettingsForScreencast)1555 TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) {
1556 static const int kScreenshareMinBitrateKbps = 800;
1557 cricket::VideoCodec codec = kVp8Codec360p;
1558 cricket::VideoSendParameters parameters;
1559 parameters.codecs.push_back(codec);
1560 parameters.options.screencast_min_bitrate =
1561 rtc::Optional<int>(kScreenshareMinBitrateKbps);
1562 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1563
1564 AddSendStream();
1565
1566 cricket::FakeVideoCapturer capturer;
1567 capturer.SetScreencast(false);
1568 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1569 cricket::VideoFormat capture_format_hd =
1570 capturer.GetSupportedFormats()->front();
1571 EXPECT_EQ(1280, capture_format_hd.width);
1572 EXPECT_EQ(720, capture_format_hd.height);
1573 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1574
1575 EXPECT_TRUE(channel_->SetSend(true));
1576
1577 EXPECT_TRUE(capturer.CaptureFrame());
1578 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1579 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1580
1581 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1582
1583 // Verify non-screencast settings.
1584 webrtc::VideoEncoderConfig encoder_config = send_stream->GetEncoderConfig();
1585 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
1586 encoder_config.content_type);
1587 EXPECT_EQ(codec.width, encoder_config.streams.front().width);
1588 EXPECT_EQ(codec.height, encoder_config.streams.front().height);
1589 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
1590 << "Non-screenshare shouldn't use min-transmit bitrate.";
1591
1592 capturer.SetScreencast(true);
1593 EXPECT_TRUE(capturer.CaptureFrame());
1594
1595 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
1596
1597 // Verify screencast settings.
1598 encoder_config = send_stream->GetEncoderConfig();
1599 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
1600 encoder_config.content_type);
1601 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
1602 encoder_config.min_transmit_bitrate_bps);
1603
1604 EXPECT_EQ(capture_format_hd.width, encoder_config.streams.front().width);
1605 EXPECT_EQ(capture_format_hd.height, encoder_config.streams.front().height);
1606 EXPECT_TRUE(encoder_config.streams[0].temporal_layer_thresholds_bps.empty());
1607
1608 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
1609 }
1610
TEST_F(WebRtcVideoChannel2Test,ConferenceModeScreencastConfiguresTemporalLayer)1611 TEST_F(WebRtcVideoChannel2Test,
1612 ConferenceModeScreencastConfiguresTemporalLayer) {
1613 static const int kConferenceScreencastTemporalBitrateBps =
1614 ScreenshareLayerConfig::GetDefault().tl0_bitrate_kbps * 1000;
1615 send_parameters_.options.conference_mode = rtc::Optional<bool>(true);
1616 channel_->SetSendParameters(send_parameters_);
1617
1618 AddSendStream();
1619
1620 cricket::FakeVideoCapturer capturer;
1621 capturer.SetScreencast(true);
1622 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1623 cricket::VideoFormat capture_format_hd =
1624 capturer.GetSupportedFormats()->front();
1625 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1626
1627 EXPECT_TRUE(channel_->SetSend(true));
1628
1629 EXPECT_TRUE(capturer.CaptureFrame());
1630 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1631 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1632
1633 webrtc::VideoEncoderConfig encoder_config = send_stream->GetEncoderConfig();
1634
1635 // Verify screencast settings.
1636 encoder_config = send_stream->GetEncoderConfig();
1637 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
1638 encoder_config.content_type);
1639 ASSERT_EQ(1u, encoder_config.streams.size());
1640 ASSERT_EQ(1u, encoder_config.streams[0].temporal_layer_thresholds_bps.size());
1641 EXPECT_EQ(kConferenceScreencastTemporalBitrateBps,
1642 encoder_config.streams[0].temporal_layer_thresholds_bps[0]);
1643
1644 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
1645 }
1646
TEST_F(WebRtcVideoChannel2Test,DISABLED_SetSendSsrcAndCname)1647 TEST_F(WebRtcVideoChannel2Test, DISABLED_SetSendSsrcAndCname) {
1648 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1649 }
1650
TEST_F(WebRtcVideoChannel2Test,DISABLED_SetSendSsrcAfterCreatingReceiveChannel)1651 TEST_F(WebRtcVideoChannel2Test,
1652 DISABLED_SetSendSsrcAfterCreatingReceiveChannel) {
1653 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1654 }
1655
TEST_F(WebRtcVideoChannel2Test,SuspendBelowMinBitrateDisabledByDefault)1656 TEST_F(WebRtcVideoChannel2Test, SuspendBelowMinBitrateDisabledByDefault) {
1657 FakeVideoSendStream* stream = AddSendStream();
1658 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1659 }
1660
TEST_F(WebRtcVideoChannel2Test,SetOptionsWithSuspendBelowMinBitrate)1661 TEST_F(WebRtcVideoChannel2Test, SetOptionsWithSuspendBelowMinBitrate) {
1662 send_parameters_.options.suspend_below_min_bitrate =
1663 rtc::Optional<bool>(true);
1664 channel_->SetSendParameters(send_parameters_);
1665
1666 FakeVideoSendStream* stream = AddSendStream();
1667 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
1668
1669 send_parameters_.options.suspend_below_min_bitrate =
1670 rtc::Optional<bool>(false);
1671 channel_->SetSendParameters(send_parameters_);
1672
1673 stream = fake_call_->GetVideoSendStreams()[0];
1674 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1675 }
1676
TEST_F(WebRtcVideoChannel2Test,Vp8DenoisingEnabledByDefault)1677 TEST_F(WebRtcVideoChannel2Test, Vp8DenoisingEnabledByDefault) {
1678 FakeVideoSendStream* stream = AddSendStream();
1679 webrtc::VideoCodecVP8 vp8_settings;
1680 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1681 EXPECT_TRUE(vp8_settings.denoisingOn);
1682 }
1683
TEST_F(WebRtcVideoChannel2Test,VerifyVp8SpecificSettings)1684 TEST_F(WebRtcVideoChannel2Test, VerifyVp8SpecificSettings) {
1685 cricket::VideoSendParameters parameters;
1686 parameters.codecs.push_back(kVp8Codec720p);
1687 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1688
1689 // Single-stream settings should apply with RTX as well (verifies that we
1690 // check number of regular SSRCs and not StreamParams::ssrcs which contains
1691 // both RTX and regular SSRCs).
1692 FakeVideoSendStream* stream = SetUpSimulcast(false, true);
1693
1694 cricket::FakeVideoCapturer capturer;
1695 capturer.SetScreencast(false);
1696 EXPECT_EQ(cricket::CS_RUNNING,
1697 capturer.Start(capturer.GetSupportedFormats()->front()));
1698 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1699 channel_->SetSend(true);
1700
1701 EXPECT_TRUE(capturer.CaptureFrame());
1702
1703 webrtc::VideoCodecVP8 vp8_settings;
1704 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1705 EXPECT_TRUE(vp8_settings.denoisingOn)
1706 << "VP8 denoising should be on by default.";
1707
1708 stream = SetDenoisingOption(parameters, false);
1709
1710 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1711 EXPECT_FALSE(vp8_settings.denoisingOn);
1712 EXPECT_TRUE(vp8_settings.automaticResizeOn);
1713 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1714
1715 stream = SetDenoisingOption(parameters, true);
1716
1717 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1718 EXPECT_TRUE(vp8_settings.denoisingOn);
1719 EXPECT_TRUE(vp8_settings.automaticResizeOn);
1720 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1721
1722 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
1723 stream = SetUpSimulcast(true, false);
1724 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1725 channel_->SetSend(true);
1726 EXPECT_TRUE(capturer.CaptureFrame());
1727
1728 EXPECT_EQ(3, stream->GetVideoStreams().size());
1729 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1730 // Autmatic resize off when using simulcast.
1731 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1732 EXPECT_TRUE(vp8_settings.frameDroppingOn);
1733
1734 // In screen-share mode, denoising is forced off and simulcast disabled.
1735 capturer.SetScreencast(true);
1736 EXPECT_TRUE(capturer.CaptureFrame());
1737 stream = SetDenoisingOption(parameters, false);
1738
1739 EXPECT_EQ(1, stream->GetVideoStreams().size());
1740 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1741 EXPECT_FALSE(vp8_settings.denoisingOn);
1742 // Resizing and frame dropping always off for screen sharing.
1743 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1744 EXPECT_FALSE(vp8_settings.frameDroppingOn);
1745
1746 stream = SetDenoisingOption(parameters, true);
1747
1748 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1749 EXPECT_FALSE(vp8_settings.denoisingOn);
1750 EXPECT_FALSE(vp8_settings.automaticResizeOn);
1751 EXPECT_FALSE(vp8_settings.frameDroppingOn);
1752
1753 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
1754 }
1755
1756 class Vp9SettingsTest : public WebRtcVideoChannel2Test {
1757 public:
Vp9SettingsTest()1758 Vp9SettingsTest() : WebRtcVideoChannel2Test() {
1759 encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP9, "VP9");
1760 }
~Vp9SettingsTest()1761 virtual ~Vp9SettingsTest() {}
1762
1763 protected:
SetUp()1764 void SetUp() override {
1765 engine_.SetExternalEncoderFactory(&encoder_factory_);
1766
1767 WebRtcVideoChannel2Test::SetUp();
1768 }
1769
TearDown()1770 void TearDown() override {
1771 // Remove references to encoder_factory_ since this will be destroyed
1772 // before channel_ and engine_.
1773 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
1774 }
1775
1776 cricket::FakeWebRtcVideoEncoderFactory encoder_factory_;
1777 };
1778
TEST_F(Vp9SettingsTest,VerifyVp9SpecificSettings)1779 TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
1780 cricket::VideoSendParameters parameters;
1781 parameters.codecs.push_back(kVp9Codec);
1782 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1783
1784 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
1785
1786 cricket::FakeVideoCapturer capturer;
1787 capturer.SetScreencast(false);
1788 EXPECT_EQ(cricket::CS_RUNNING,
1789 capturer.Start(capturer.GetSupportedFormats()->front()));
1790 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1791 channel_->SetSend(true);
1792
1793 EXPECT_TRUE(capturer.CaptureFrame());
1794
1795 webrtc::VideoCodecVP9 vp9_settings;
1796 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1797 EXPECT_FALSE(vp9_settings.denoisingOn)
1798 << "VP9 denoising should be off by default.";
1799
1800 stream = SetDenoisingOption(parameters, false);
1801
1802 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1803 EXPECT_FALSE(vp9_settings.denoisingOn);
1804 // Frame dropping always on for real time video.
1805 EXPECT_TRUE(vp9_settings.frameDroppingOn);
1806
1807 stream = SetDenoisingOption(parameters, true);
1808
1809 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1810 EXPECT_TRUE(vp9_settings.denoisingOn);
1811 EXPECT_TRUE(vp9_settings.frameDroppingOn);
1812
1813 // In screen-share mode, denoising is forced off.
1814 capturer.SetScreencast(true);
1815 EXPECT_TRUE(capturer.CaptureFrame());
1816 stream = SetDenoisingOption(parameters, false);
1817
1818 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1819 EXPECT_FALSE(vp9_settings.denoisingOn);
1820 // Frame dropping always off for screen sharing.
1821 EXPECT_FALSE(vp9_settings.frameDroppingOn);
1822
1823 stream = SetDenoisingOption(parameters, false);
1824
1825 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
1826 EXPECT_FALSE(vp9_settings.denoisingOn);
1827 EXPECT_FALSE(vp9_settings.frameDroppingOn);
1828
1829 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
1830 }
1831
TEST_F(WebRtcVideoChannel2Test,DISABLED_MultipleSendStreamsWithOneCapturer)1832 TEST_F(WebRtcVideoChannel2Test, DISABLED_MultipleSendStreamsWithOneCapturer) {
1833 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1834 }
1835
TEST_F(WebRtcVideoChannel2Test,DISABLED_SendReceiveBitratesStats)1836 TEST_F(WebRtcVideoChannel2Test, DISABLED_SendReceiveBitratesStats) {
1837 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1838 }
1839
TEST_F(WebRtcVideoChannel2Test,AdaptsOnOveruse)1840 TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruse) {
1841 TestCpuAdaptation(true, false);
1842 }
1843
TEST_F(WebRtcVideoChannel2Test,DoesNotAdaptOnOveruseWhenDisabled)1844 TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenDisabled) {
1845 TestCpuAdaptation(false, false);
1846 }
1847
TEST_F(WebRtcVideoChannel2Test,DoesNotAdaptOnOveruseWhenScreensharing)1848 TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenScreensharing) {
1849 TestCpuAdaptation(true, true);
1850 }
1851
TestCpuAdaptation(bool enable_overuse,bool is_screenshare)1852 void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse,
1853 bool is_screenshare) {
1854 cricket::VideoCodec codec = kVp8Codec720p;
1855 cricket::VideoSendParameters parameters;
1856 parameters.codecs.push_back(codec);
1857 if (!enable_overuse) {
1858 parameters.options.cpu_overuse_detection = rtc::Optional<bool>(false);
1859 }
1860 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1861
1862 AddSendStream();
1863
1864 cricket::FakeVideoCapturer capturer;
1865 capturer.SetScreencast(is_screenshare);
1866 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1867 EXPECT_EQ(cricket::CS_RUNNING,
1868 capturer.Start(capturer.GetSupportedFormats()->front()));
1869
1870 EXPECT_TRUE(channel_->SetSend(true));
1871
1872 // Trigger overuse.
1873 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1874 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1875 webrtc::LoadObserver* overuse_callback =
1876 send_stream->GetConfig().overuse_callback;
1877 ASSERT_TRUE(overuse_callback != NULL);
1878 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
1879
1880 EXPECT_TRUE(capturer.CaptureFrame());
1881 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1882
1883 if (enable_overuse && !is_screenshare) {
1884 EXPECT_LT(send_stream->GetLastWidth(), codec.width);
1885 EXPECT_LT(send_stream->GetLastHeight(), codec.height);
1886 } else {
1887 EXPECT_EQ(codec.width, send_stream->GetLastWidth());
1888 EXPECT_EQ(codec.height, send_stream->GetLastHeight());
1889 }
1890
1891 // Trigger underuse which should go back to normal resolution.
1892 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse);
1893 EXPECT_TRUE(capturer.CaptureFrame());
1894
1895 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
1896
1897 EXPECT_EQ(codec.width, send_stream->GetLastWidth());
1898 EXPECT_EQ(codec.height, send_stream->GetLastHeight());
1899
1900 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
1901 }
1902
TEST_F(WebRtcVideoChannel2Test,EstimatesNtpStartTimeCorrectly)1903 TEST_F(WebRtcVideoChannel2Test, EstimatesNtpStartTimeCorrectly) {
1904 // Start at last timestamp to verify that wraparounds are estimated correctly.
1905 static const uint32_t kInitialTimestamp = 0xFFFFFFFFu;
1906 static const int64_t kInitialNtpTimeMs = 1247891230;
1907 static const int kFrameOffsetMs = 20;
1908 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
1909
1910 FakeVideoReceiveStream* stream = AddRecvStream();
1911 cricket::FakeVideoRenderer renderer;
1912 EXPECT_TRUE(channel_->SetRenderer(last_ssrc_, &renderer));
1913
1914 webrtc::VideoFrame video_frame;
1915 CreateBlackFrame(&video_frame, 4, 4);
1916 video_frame.set_timestamp(kInitialTimestamp);
1917 // Initial NTP time is not available on the first frame, but should still be
1918 // able to be estimated.
1919 stream->InjectFrame(video_frame, 0);
1920
1921 EXPECT_EQ(1, renderer.num_rendered_frames());
1922
1923 // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which
1924 // triggers a constant-overflow warning, hence we're calculating it explicitly
1925 // here.
1926 video_frame.set_timestamp(kFrameOffsetMs * 90 - 1);
1927 video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs);
1928 stream->InjectFrame(video_frame, 0);
1929
1930 EXPECT_EQ(2, renderer.num_rendered_frames());
1931
1932 // Verify that NTP time has been correctly deduced.
1933 cricket::VideoMediaInfo info;
1934 ASSERT_TRUE(channel_->GetStats(&info));
1935 ASSERT_EQ(1u, info.receivers.size());
1936 EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms);
1937 }
1938
TEST_F(WebRtcVideoChannel2Test,SetDefaultSendCodecs)1939 TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) {
1940 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
1941
1942 VideoCodec codec;
1943 EXPECT_TRUE(channel_->GetSendCodec(&codec));
1944 EXPECT_TRUE(codec.Matches(engine_.codecs()[0]));
1945
1946 // Using a RTX setup to verify that the default RTX payload type is good.
1947 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
1948 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
1949 FakeVideoSendStream* stream = AddSendStream(
1950 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1951 webrtc::VideoSendStream::Config config = stream->GetConfig();
1952
1953 // Make sure NACK and FEC are enabled on the correct payload types.
1954 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
1955 EXPECT_EQ(default_ulpfec_codec_.id, config.rtp.fec.ulpfec_payload_type);
1956 EXPECT_EQ(default_red_codec_.id, config.rtp.fec.red_payload_type);
1957
1958 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
1959 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
1960 VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_);
1961 // TODO(juberti): Check RTCP, PLI, TMMBR.
1962 }
1963
TEST_F(WebRtcVideoChannel2Test,SetSendCodecsWithoutFec)1964 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFec) {
1965 cricket::VideoSendParameters parameters;
1966 parameters.codecs.push_back(kVp8Codec);
1967 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1968
1969 FakeVideoSendStream* stream = AddSendStream();
1970 webrtc::VideoSendStream::Config config = stream->GetConfig();
1971
1972 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type);
1973 EXPECT_EQ(-1, config.rtp.fec.red_payload_type);
1974 }
1975
TEST_F(WebRtcVideoChannel2Test,SetSendCodecRejectsRtxWithoutAssociatedPayloadType)1976 TEST_F(WebRtcVideoChannel2Test,
1977 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
1978 cricket::VideoSendParameters parameters;
1979 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
1980 parameters.codecs.push_back(rtx_codec);
1981 EXPECT_FALSE(channel_->SetSendParameters(parameters))
1982 << "RTX codec without associated payload type should be rejected.";
1983 }
1984
TEST_F(WebRtcVideoChannel2Test,SetSendCodecRejectsRtxWithoutMatchingVideoCodec)1985 TEST_F(WebRtcVideoChannel2Test,
1986 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
1987 cricket::VideoSendParameters parameters;
1988 cricket::VideoCodec rtx_codec =
1989 cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id);
1990 parameters.codecs.push_back(kVp8Codec);
1991 parameters.codecs.push_back(rtx_codec);
1992 ASSERT_TRUE(channel_->SetSendParameters(parameters));
1993
1994 cricket::VideoCodec rtx_codec2 =
1995 cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id + 1);
1996 parameters.codecs.pop_back();
1997 parameters.codecs.push_back(rtx_codec2);
1998 EXPECT_FALSE(channel_->SetSendParameters(parameters))
1999 << "RTX without matching video codec should be rejected.";
2000 }
2001
TEST_F(WebRtcVideoChannel2Test,SetSendCodecsWithoutFecDisablesFec)2002 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFecDisablesFec) {
2003 cricket::VideoSendParameters parameters;
2004 parameters.codecs.push_back(kVp8Codec);
2005 parameters.codecs.push_back(kUlpfecCodec);
2006 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2007
2008 FakeVideoSendStream* stream = AddSendStream();
2009 webrtc::VideoSendStream::Config config = stream->GetConfig();
2010
2011 EXPECT_EQ(kUlpfecCodec.id, config.rtp.fec.ulpfec_payload_type);
2012
2013 parameters.codecs.pop_back();
2014 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2015 stream = fake_call_->GetVideoSendStreams()[0];
2016 ASSERT_TRUE(stream != NULL);
2017 config = stream->GetConfig();
2018 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type)
2019 << "SetSendCodec without FEC should disable current FEC.";
2020 }
2021
TEST_F(WebRtcVideoChannel2Test,SetSendCodecsChangesExistingStreams)2022 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsChangesExistingStreams) {
2023 cricket::VideoSendParameters parameters;
2024 parameters.codecs.push_back(kVp8Codec720p);
2025 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2026 channel_->SetSend(true);
2027
2028 FakeVideoSendStream* stream = AddSendStream();
2029
2030 cricket::FakeVideoCapturer capturer;
2031 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
2032 EXPECT_EQ(cricket::CS_RUNNING,
2033 capturer.Start(capturer.GetSupportedFormats()->front()));
2034 EXPECT_TRUE(capturer.CaptureFrame());
2035
2036 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
2037 EXPECT_EQ(kVp8Codec720p.width, streams[0].width);
2038 EXPECT_EQ(kVp8Codec720p.height, streams[0].height);
2039
2040 parameters.codecs.clear();
2041 parameters.codecs.push_back(kVp8Codec360p);
2042 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2043 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
2044 EXPECT_EQ(kVp8Codec360p.width, streams[0].width);
2045 EXPECT_EQ(kVp8Codec360p.height, streams[0].height);
2046 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
2047 }
2048
TEST_F(WebRtcVideoChannel2Test,SetSendCodecsWithBitrates)2049 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithBitrates) {
2050 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
2051 200000);
2052 }
2053
TEST_F(WebRtcVideoChannel2Test,SetSendCodecsWithHighMaxBitrate)2054 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithHighMaxBitrate) {
2055 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
2056 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
2057 ASSERT_EQ(1u, streams.size());
2058 EXPECT_EQ(10000000, streams[0].max_bitrate_bps);
2059 }
2060
TEST_F(WebRtcVideoChannel2Test,SetSendCodecsWithoutBitratesUsesCorrectDefaults)2061 TEST_F(WebRtcVideoChannel2Test,
2062 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
2063 SetSendCodecsShouldWorkForBitrates(
2064 "", 0, "", -1, "", -1);
2065 }
2066
TEST_F(WebRtcVideoChannel2Test,SetSendCodecsCapsMinAndStartBitrate)2067 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsCapsMinAndStartBitrate) {
2068 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
2069 }
2070
TEST_F(WebRtcVideoChannel2Test,SetSendCodecsRejectsMaxLessThanMinBitrate)2071 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectsMaxLessThanMinBitrate) {
2072 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "300";
2073 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "200";
2074 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
2075 }
2076
TEST_F(WebRtcVideoChannel2Test,SetMaxSendBandwidthShouldPreserveOtherBitrates)2077 TEST_F(WebRtcVideoChannel2Test,
2078 SetMaxSendBandwidthShouldPreserveOtherBitrates) {
2079 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
2080 200000);
2081 send_parameters_.max_bandwidth_bps = 300000;
2082 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2083 EXPECT_EQ(100000, fake_call_->GetConfig().bitrate_config.min_bitrate_bps)
2084 << "Setting max bitrate should keep previous min bitrate.";
2085 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.start_bitrate_bps)
2086 << "Setting max bitrate should not reset start bitrate.";
2087 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2088 }
2089
TEST_F(WebRtcVideoChannel2Test,SetMaxSendBandwidthShouldBeRemovable)2090 TEST_F(WebRtcVideoChannel2Test, SetMaxSendBandwidthShouldBeRemovable) {
2091 send_parameters_.max_bandwidth_bps = 300000;
2092 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2093 EXPECT_EQ(300000, fake_call_->GetConfig().bitrate_config.max_bitrate_bps);
2094 // <= 0 means disable (infinite) max bitrate.
2095 send_parameters_.max_bandwidth_bps = 0;
2096 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2097 EXPECT_EQ(-1, fake_call_->GetConfig().bitrate_config.max_bitrate_bps)
2098 << "Setting zero max bitrate did not reset start bitrate.";
2099 }
2100
TEST_F(WebRtcVideoChannel2Test,SetMaxSendBitrateCanIncreaseSenderBitrate)2101 TEST_F(WebRtcVideoChannel2Test, SetMaxSendBitrateCanIncreaseSenderBitrate) {
2102 cricket::VideoSendParameters parameters;
2103 parameters.codecs.push_back(kVp8Codec720p);
2104 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2105 channel_->SetSend(true);
2106
2107 FakeVideoSendStream* stream = AddSendStream();
2108
2109 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
2110 int initial_max_bitrate_bps = streams[0].max_bitrate_bps;
2111 EXPECT_GT(initial_max_bitrate_bps, 0);
2112
2113 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
2114 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2115 streams = stream->GetVideoStreams();
2116 EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps);
2117 }
2118
TEST_F(WebRtcVideoChannel2Test,SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate)2119 TEST_F(WebRtcVideoChannel2Test,
2120 SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) {
2121 cricket::VideoSendParameters parameters;
2122 parameters.codecs.push_back(kVp8Codec720p);
2123 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2124 channel_->SetSend(true);
2125
2126 FakeVideoSendStream* stream = AddSendStream(
2127 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
2128
2129 // Send a frame to make sure this scales up to >1 stream (simulcast).
2130 cricket::FakeVideoCapturer capturer;
2131 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &capturer));
2132 EXPECT_EQ(cricket::CS_RUNNING,
2133 capturer.Start(capturer.GetSupportedFormats()->front()));
2134 EXPECT_TRUE(capturer.CaptureFrame());
2135
2136 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
2137 ASSERT_GT(streams.size(), 1u)
2138 << "Without simulcast this test doesn't make sense.";
2139 int initial_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
2140 EXPECT_GT(initial_max_bitrate_bps, 0);
2141
2142 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
2143 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2144 streams = stream->GetVideoStreams();
2145 int increased_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
2146 EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps);
2147
2148 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], nullptr));
2149 }
2150
TEST_F(WebRtcVideoChannel2Test,SetSendCodecsWithMaxQuantization)2151 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMaxQuantization) {
2152 static const char* kMaxQuantization = "21";
2153 cricket::VideoSendParameters parameters;
2154 parameters.codecs.push_back(kVp8Codec);
2155 parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
2156 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2157 EXPECT_EQ(static_cast<unsigned int>(atoi(kMaxQuantization)),
2158 AddSendStream()->GetVideoStreams().back().max_qp);
2159
2160 VideoCodec codec;
2161 EXPECT_TRUE(channel_->GetSendCodec(&codec));
2162 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
2163 }
2164
TEST_F(WebRtcVideoChannel2Test,SetSendCodecsRejectBadDimensions)2165 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadDimensions) {
2166 cricket::VideoSendParameters parameters;
2167 parameters.codecs.push_back(kVp8Codec);
2168
2169 parameters.codecs[0].width = 0;
2170 EXPECT_FALSE(channel_->SetSendParameters(parameters))
2171 << "Codec set though codec width is zero.";
2172
2173 parameters.codecs[0].width = kVp8Codec.width;
2174 parameters.codecs[0].height = 0;
2175 EXPECT_FALSE(channel_->SetSendParameters(parameters))
2176 << "Codec set though codec height is zero.";
2177 }
2178
TEST_F(WebRtcVideoChannel2Test,SetSendCodecsRejectBadPayloadTypes)2179 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) {
2180 // TODO(pbos): Should we only allow the dynamic range?
2181 static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
2182 cricket::VideoSendParameters parameters;
2183 parameters.codecs.push_back(kVp8Codec);
2184 for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
2185 parameters.codecs[0].id = kIncorrectPayloads[i];
2186 EXPECT_FALSE(channel_->SetSendParameters(parameters))
2187 << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted.";
2188 }
2189 }
2190
TEST_F(WebRtcVideoChannel2Test,SetSendCodecsAcceptAllValidPayloadTypes)2191 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptAllValidPayloadTypes) {
2192 cricket::VideoSendParameters parameters;
2193 parameters.codecs.push_back(kVp8Codec);
2194 for (int payload_type = 0; payload_type <= 127; ++payload_type) {
2195 parameters.codecs[0].id = payload_type;
2196 EXPECT_TRUE(channel_->SetSendParameters(parameters))
2197 << "Payload type '" << payload_type << "' rejected.";
2198 }
2199 }
2200
TEST_F(WebRtcVideoChannel2Test,SetRecvCodecsWithOnlyVp8)2201 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithOnlyVp8) {
2202 cricket::VideoRecvParameters parameters;
2203 parameters.codecs.push_back(kVp8Codec);
2204 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2205 }
2206
2207 // Test that we set our inbound RTX codecs properly.
TEST_F(WebRtcVideoChannel2Test,SetRecvCodecsWithRtx)2208 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithRtx) {
2209 cricket::VideoRecvParameters parameters;
2210 parameters.codecs.push_back(kVp8Codec);
2211 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
2212 parameters.codecs.push_back(rtx_codec);
2213 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
2214 << "RTX codec without associated payload should be rejected.";
2215
2216 parameters.codecs[1].SetParam("apt", kVp8Codec.id + 1);
2217 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
2218 << "RTX codec with invalid associated payload type should be rejected.";
2219
2220 parameters.codecs[1].SetParam("apt", kVp8Codec.id);
2221 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2222
2223 cricket::VideoCodec rtx_codec2(97, "rtx", 0, 0, 0, 0);
2224 rtx_codec2.SetParam("apt", rtx_codec.id);
2225 parameters.codecs.push_back(rtx_codec2);
2226
2227 EXPECT_FALSE(channel_->SetRecvParameters(parameters)) <<
2228 "RTX codec with another RTX as associated payload type should be "
2229 "rejected.";
2230 }
2231
TEST_F(WebRtcVideoChannel2Test,SetRecvCodecsDifferentPayloadType)2232 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentPayloadType) {
2233 cricket::VideoRecvParameters parameters;
2234 parameters.codecs.push_back(kVp8Codec);
2235 parameters.codecs[0].id = 99;
2236 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2237 }
2238
TEST_F(WebRtcVideoChannel2Test,SetRecvCodecsAcceptDefaultCodecs)2239 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsAcceptDefaultCodecs) {
2240 cricket::VideoRecvParameters parameters;
2241 parameters.codecs = engine_.codecs();
2242 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2243
2244 FakeVideoReceiveStream* stream = AddRecvStream();
2245 webrtc::VideoReceiveStream::Config config = stream->GetConfig();
2246 EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].payload_name);
2247 EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type);
2248 }
2249
TEST_F(WebRtcVideoChannel2Test,SetRecvCodecsRejectUnsupportedCodec)2250 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) {
2251 cricket::VideoRecvParameters parameters;
2252 parameters.codecs.push_back(kVp8Codec);
2253 parameters.codecs.push_back(VideoCodec(101, "WTF3", 640, 400, 30, 0));
2254 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
2255 }
2256
2257 // TODO(pbos): Enable VP9 through external codec support
TEST_F(WebRtcVideoChannel2Test,DISABLED_SetRecvCodecsAcceptsMultipleVideoCodecs)2258 TEST_F(WebRtcVideoChannel2Test,
2259 DISABLED_SetRecvCodecsAcceptsMultipleVideoCodecs) {
2260 cricket::VideoRecvParameters parameters;
2261 parameters.codecs.push_back(kVp8Codec);
2262 parameters.codecs.push_back(kVp9Codec);
2263 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2264 }
2265
TEST_F(WebRtcVideoChannel2Test,DISABLED_SetRecvCodecsSetsFecForAllVideoCodecs)2266 TEST_F(WebRtcVideoChannel2Test,
2267 DISABLED_SetRecvCodecsSetsFecForAllVideoCodecs) {
2268 cricket::VideoRecvParameters parameters;
2269 parameters.codecs.push_back(kVp8Codec);
2270 parameters.codecs.push_back(kVp9Codec);
2271 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2272 FAIL(); // TODO(pbos): Verify that the FEC parameters are set for all codecs.
2273 }
2274
TEST_F(WebRtcVideoChannel2Test,SetRecvCodecsWithoutFecDisablesFec)2275 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithoutFecDisablesFec) {
2276 cricket::VideoSendParameters send_parameters;
2277 send_parameters.codecs.push_back(kVp8Codec);
2278 send_parameters.codecs.push_back(kUlpfecCodec);
2279 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
2280
2281 FakeVideoReceiveStream* stream = AddRecvStream();
2282 webrtc::VideoReceiveStream::Config config = stream->GetConfig();
2283
2284 EXPECT_EQ(kUlpfecCodec.id, config.rtp.fec.ulpfec_payload_type);
2285
2286 cricket::VideoRecvParameters recv_parameters;
2287 recv_parameters.codecs.push_back(kVp8Codec);
2288 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
2289 stream = fake_call_->GetVideoReceiveStreams()[0];
2290 ASSERT_TRUE(stream != NULL);
2291 config = stream->GetConfig();
2292 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type)
2293 << "SetSendCodec without FEC should disable current FEC.";
2294 }
2295
TEST_F(WebRtcVideoChannel2Test,SetSendCodecsRejectDuplicateFecPayloads)2296 TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectDuplicateFecPayloads) {
2297 cricket::VideoRecvParameters parameters;
2298 parameters.codecs.push_back(kVp8Codec);
2299 parameters.codecs.push_back(kRedCodec);
2300 parameters.codecs[1].id = parameters.codecs[0].id;
2301 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
2302 }
2303
TEST_F(WebRtcVideoChannel2Test,SetRecvCodecsRejectDuplicateCodecPayloads)2304 TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectDuplicateCodecPayloads) {
2305 cricket::VideoRecvParameters parameters;
2306 parameters.codecs.push_back(kVp8Codec);
2307 parameters.codecs.push_back(kVp9Codec);
2308 parameters.codecs[1].id = parameters.codecs[0].id;
2309 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
2310 }
2311
TEST_F(WebRtcVideoChannel2Test,SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes)2312 TEST_F(WebRtcVideoChannel2Test,
2313 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
2314 cricket::VideoRecvParameters parameters;
2315 parameters.codecs.push_back(kVp8Codec);
2316 parameters.codecs.push_back(kVp8Codec);
2317 parameters.codecs[1].id += 1;
2318 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2319 }
2320
2321 // Test that setting the same codecs but with a different order and preference
2322 // doesn't result in the stream being recreated.
TEST_F(WebRtcVideoChannel2Test,SetRecvCodecsDifferentOrderAndPreferenceDoesntRecreateStream)2323 TEST_F(WebRtcVideoChannel2Test,
2324 SetRecvCodecsDifferentOrderAndPreferenceDoesntRecreateStream) {
2325 cricket::VideoRecvParameters parameters1;
2326 parameters1.codecs.push_back(kVp8Codec);
2327 parameters1.codecs.push_back(kRedCodec);
2328 EXPECT_TRUE(channel_->SetRecvParameters(parameters1));
2329
2330 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2331 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2332
2333 cricket::VideoRecvParameters parameters2;
2334 parameters2.codecs.push_back(kRedCodec);
2335 parameters2.codecs.push_back(kVp8Codec);
2336 parameters2.codecs[1].preference += 1;
2337 EXPECT_TRUE(channel_->SetRecvParameters(parameters2));
2338 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2339 }
2340
TEST_F(WebRtcVideoChannel2Test,SendStreamNotSendingByDefault)2341 TEST_F(WebRtcVideoChannel2Test, SendStreamNotSendingByDefault) {
2342 EXPECT_FALSE(AddSendStream()->IsSending());
2343 }
2344
TEST_F(WebRtcVideoChannel2Test,ReceiveStreamReceivingByDefault)2345 TEST_F(WebRtcVideoChannel2Test, ReceiveStreamReceivingByDefault) {
2346 EXPECT_TRUE(AddRecvStream()->IsReceiving());
2347 }
2348
TEST_F(WebRtcVideoChannel2Test,SetSend)2349 TEST_F(WebRtcVideoChannel2Test, SetSend) {
2350 FakeVideoSendStream* stream = AddSendStream();
2351 EXPECT_FALSE(stream->IsSending());
2352
2353 // false->true
2354 EXPECT_TRUE(channel_->SetSend(true));
2355 EXPECT_TRUE(stream->IsSending());
2356 // true->true
2357 EXPECT_TRUE(channel_->SetSend(true));
2358 EXPECT_TRUE(stream->IsSending());
2359 // true->false
2360 EXPECT_TRUE(channel_->SetSend(false));
2361 EXPECT_FALSE(stream->IsSending());
2362 // false->false
2363 EXPECT_TRUE(channel_->SetSend(false));
2364 EXPECT_FALSE(stream->IsSending());
2365
2366 EXPECT_TRUE(channel_->SetSend(true));
2367 FakeVideoSendStream* new_stream = AddSendStream();
2368 EXPECT_TRUE(new_stream->IsSending())
2369 << "Send stream created after SetSend(true) not sending initially.";
2370 }
2371
2372 // This test verifies DSCP settings are properly applied on video media channel.
TEST_F(WebRtcVideoChannel2Test,TestSetDscpOptions)2373 TEST_F(WebRtcVideoChannel2Test, TestSetDscpOptions) {
2374 rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
2375 new cricket::FakeNetworkInterface);
2376 channel_->SetInterface(network_interface.get());
2377 cricket::VideoSendParameters parameters = send_parameters_;
2378 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2379 EXPECT_EQ(rtc::DSCP_NO_CHANGE, network_interface->dscp());
2380 parameters.options.dscp = rtc::Optional<bool>(true);
2381 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2382 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
2383 // Verify previous value is not modified if dscp option is not set.
2384 cricket::VideoSendParameters parameters1 = send_parameters_;
2385 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
2386 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
2387 parameters1.options.dscp = rtc::Optional<bool>(false);
2388 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
2389 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
2390 channel_->SetInterface(NULL);
2391 }
2392
2393 // This test verifies that the RTCP reduced size mode is properly applied to
2394 // send video streams.
TEST_F(WebRtcVideoChannel2Test,TestSetSendRtcpReducedSize)2395 TEST_F(WebRtcVideoChannel2Test, TestSetSendRtcpReducedSize) {
2396 // Create stream, expecting that default mode is "compound".
2397 FakeVideoSendStream* stream1 = AddSendStream();
2398 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
2399
2400 // Now enable reduced size mode.
2401 send_parameters_.rtcp.reduced_size = true;
2402 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2403 stream1 = fake_call_->GetVideoSendStreams()[0];
2404 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
2405
2406 // Create a new stream and ensure it picks up the reduced size mode.
2407 FakeVideoSendStream* stream2 = AddSendStream();
2408 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
2409 }
2410
2411 // This test verifies that the RTCP reduced size mode is properly applied to
2412 // receive video streams.
TEST_F(WebRtcVideoChannel2Test,TestSetRecvRtcpReducedSize)2413 TEST_F(WebRtcVideoChannel2Test, TestSetRecvRtcpReducedSize) {
2414 // Create stream, expecting that default mode is "compound".
2415 FakeVideoReceiveStream* stream1 = AddRecvStream();
2416 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
2417
2418 // Now enable reduced size mode.
2419 recv_parameters_.rtcp.reduced_size = true;
2420 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
2421 stream1 = fake_call_->GetVideoReceiveStreams()[0];
2422 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
2423
2424 // Create a new stream and ensure it picks up the reduced size mode.
2425 FakeVideoReceiveStream* stream2 = AddRecvStream();
2426 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
2427 }
2428
TEST_F(WebRtcVideoChannel2Test,OnReadyToSendSignalsNetworkState)2429 TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) {
2430 EXPECT_EQ(webrtc::kNetworkUp, fake_call_->GetNetworkState());
2431
2432 channel_->OnReadyToSend(false);
2433 EXPECT_EQ(webrtc::kNetworkDown, fake_call_->GetNetworkState());
2434
2435 channel_->OnReadyToSend(true);
2436 EXPECT_EQ(webrtc::kNetworkUp, fake_call_->GetNetworkState());
2437 }
2438
TEST_F(WebRtcVideoChannel2Test,GetStatsReportsSentCodecName)2439 TEST_F(WebRtcVideoChannel2Test, GetStatsReportsSentCodecName) {
2440 cricket::VideoSendParameters parameters;
2441 parameters.codecs.push_back(kVp8Codec);
2442 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2443
2444 AddSendStream();
2445
2446 cricket::VideoMediaInfo info;
2447 ASSERT_TRUE(channel_->GetStats(&info));
2448 EXPECT_EQ(kVp8Codec.name, info.senders[0].codec_name);
2449 }
2450
TEST_F(WebRtcVideoChannel2Test,GetStatsReportsEncoderImplementationName)2451 TEST_F(WebRtcVideoChannel2Test, GetStatsReportsEncoderImplementationName) {
2452 FakeVideoSendStream* stream = AddSendStream();
2453 webrtc::VideoSendStream::Stats stats;
2454 stats.encoder_implementation_name = "encoder_implementation_name";
2455 stream->SetStats(stats);
2456
2457 cricket::VideoMediaInfo info;
2458 ASSERT_TRUE(channel_->GetStats(&info));
2459 EXPECT_EQ(stats.encoder_implementation_name,
2460 info.senders[0].encoder_implementation_name);
2461 }
2462
TEST_F(WebRtcVideoChannel2Test,GetStatsReportsCpuOveruseMetrics)2463 TEST_F(WebRtcVideoChannel2Test, GetStatsReportsCpuOveruseMetrics) {
2464 FakeVideoSendStream* stream = AddSendStream();
2465 webrtc::VideoSendStream::Stats stats;
2466 stats.avg_encode_time_ms = 13;
2467 stats.encode_usage_percent = 42;
2468 stream->SetStats(stats);
2469
2470 cricket::VideoMediaInfo info;
2471 ASSERT_TRUE(channel_->GetStats(&info));
2472 EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
2473 EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
2474 }
2475
TEST_F(WebRtcVideoChannel2Test,GetStatsReportsUpperResolution)2476 TEST_F(WebRtcVideoChannel2Test, GetStatsReportsUpperResolution) {
2477 FakeVideoSendStream* stream = AddSendStream();
2478 webrtc::VideoSendStream::Stats stats;
2479 stats.substreams[17].width = 123;
2480 stats.substreams[17].height = 40;
2481 stats.substreams[42].width = 80;
2482 stats.substreams[42].height = 31;
2483 stats.substreams[11].width = 20;
2484 stats.substreams[11].height = 90;
2485 stream->SetStats(stats);
2486
2487 cricket::VideoMediaInfo info;
2488 ASSERT_TRUE(channel_->GetStats(&info));
2489 ASSERT_EQ(1u, info.senders.size());
2490 EXPECT_EQ(123, info.senders[0].send_frame_width);
2491 EXPECT_EQ(90, info.senders[0].send_frame_height);
2492 }
2493
TEST_F(WebRtcVideoChannel2Test,GetStatsTracksAdaptationStats)2494 TEST_F(WebRtcVideoChannel2Test, GetStatsTracksAdaptationStats) {
2495 AddSendStream(cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
2496
2497 // Capture format VGA.
2498 cricket::FakeVideoCapturer video_capturer_vga;
2499 const std::vector<cricket::VideoFormat>* formats =
2500 video_capturer_vga.GetSupportedFormats();
2501 cricket::VideoFormat capture_format_vga = (*formats)[1];
2502 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_vga.Start(capture_format_vga));
2503 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer_vga));
2504 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
2505
2506 cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0);
2507 cricket::VideoSendParameters parameters;
2508 parameters.codecs.push_back(send_codec);
2509 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2510 EXPECT_TRUE(channel_->SetSend(true));
2511
2512 // Verify that the CpuOveruseObserver is registered and trigger downgrade.
2513 parameters.options.cpu_overuse_detection = rtc::Optional<bool>(true);
2514 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2515
2516 // Trigger overuse.
2517 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2518 webrtc::LoadObserver* overuse_callback =
2519 fake_call_->GetVideoSendStreams().front()->GetConfig().overuse_callback;
2520 ASSERT_TRUE(overuse_callback != NULL);
2521 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
2522
2523 // Capture format VGA -> adapt (OnCpuResolutionRequest downgrade) -> VGA/2.
2524 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
2525 cricket::VideoMediaInfo info;
2526 EXPECT_TRUE(channel_->GetStats(&info));
2527 ASSERT_EQ(1U, info.senders.size());
2528 EXPECT_EQ(1, info.senders[0].adapt_changes);
2529 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU,
2530 info.senders[0].adapt_reason);
2531
2532 // Trigger upgrade and verify that we adapt back up to VGA.
2533 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse);
2534 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
2535 info.Clear();
2536 EXPECT_TRUE(channel_->GetStats(&info));
2537 ASSERT_EQ(1U, info.senders.size());
2538 EXPECT_EQ(2, info.senders[0].adapt_changes);
2539 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_NONE,
2540 info.senders[0].adapt_reason);
2541
2542 // No capturer (no adapter). Adapt changes from old adapter should be kept.
2543 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL));
2544 info.Clear();
2545 EXPECT_TRUE(channel_->GetStats(&info));
2546 ASSERT_EQ(1U, info.senders.size());
2547 EXPECT_EQ(2, info.senders[0].adapt_changes);
2548 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_NONE,
2549 info.senders[0].adapt_reason);
2550
2551 // Set new capturer, capture format HD.
2552 cricket::FakeVideoCapturer video_capturer_hd;
2553 cricket::VideoFormat capture_format_hd = (*formats)[0];
2554 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_hd.Start(capture_format_hd));
2555 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer_hd));
2556 EXPECT_TRUE(video_capturer_hd.CaptureFrame());
2557
2558 // Trigger overuse, HD -> adapt (OnCpuResolutionRequest downgrade) -> HD/2.
2559 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
2560 EXPECT_TRUE(video_capturer_hd.CaptureFrame());
2561 info.Clear();
2562 EXPECT_TRUE(channel_->GetStats(&info));
2563 ASSERT_EQ(1U, info.senders.size());
2564 EXPECT_EQ(3, info.senders[0].adapt_changes);
2565 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU,
2566 info.senders[0].adapt_reason);
2567
2568 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL));
2569 }
2570
TEST_F(WebRtcVideoChannel2Test,GetStatsTracksAdaptationAndBandwidthStats)2571 TEST_F(WebRtcVideoChannel2Test, GetStatsTracksAdaptationAndBandwidthStats) {
2572 AddSendStream(cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
2573
2574 // Capture format VGA.
2575 cricket::FakeVideoCapturer video_capturer_vga;
2576 const std::vector<cricket::VideoFormat>* formats =
2577 video_capturer_vga.GetSupportedFormats();
2578 cricket::VideoFormat capture_format_vga = (*formats)[1];
2579 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_vga.Start(capture_format_vga));
2580 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], &video_capturer_vga));
2581 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
2582
2583 cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0);
2584 cricket::VideoSendParameters parameters;
2585 parameters.codecs.push_back(send_codec);
2586 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2587 EXPECT_TRUE(channel_->SetSend(true));
2588
2589 // Verify that the CpuOveruseObserver is registered and trigger downgrade.
2590 parameters.options.cpu_overuse_detection = rtc::Optional<bool>(true);
2591 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2592
2593 // Trigger overuse -> adapt CPU.
2594 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2595 webrtc::LoadObserver* overuse_callback =
2596 fake_call_->GetVideoSendStreams().front()->GetConfig().overuse_callback;
2597 ASSERT_TRUE(overuse_callback != NULL);
2598 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
2599 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
2600 cricket::VideoMediaInfo info;
2601 EXPECT_TRUE(channel_->GetStats(&info));
2602 ASSERT_EQ(1U, info.senders.size());
2603 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU,
2604 info.senders[0].adapt_reason);
2605
2606 // Set bandwidth limitation stats for the stream -> adapt CPU + BW.
2607 webrtc::VideoSendStream::Stats stats;
2608 stats.bw_limited_resolution = true;
2609 fake_call_->GetVideoSendStreams().front()->SetStats(stats);
2610 info.Clear();
2611 EXPECT_TRUE(channel_->GetStats(&info));
2612 ASSERT_EQ(1U, info.senders.size());
2613 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU +
2614 CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH,
2615 info.senders[0].adapt_reason);
2616
2617 // Trigger upgrade -> adapt BW.
2618 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse);
2619 EXPECT_TRUE(video_capturer_vga.CaptureFrame());
2620 info.Clear();
2621 EXPECT_TRUE(channel_->GetStats(&info));
2622 ASSERT_EQ(1U, info.senders.size());
2623 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH,
2624 info.senders[0].adapt_reason);
2625
2626 // Reset bandwidth limitation state -> adapt NONE.
2627 stats.bw_limited_resolution = false;
2628 fake_call_->GetVideoSendStreams().front()->SetStats(stats);
2629 info.Clear();
2630 EXPECT_TRUE(channel_->GetStats(&info));
2631 ASSERT_EQ(1U, info.senders.size());
2632 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_NONE,
2633 info.senders[0].adapt_reason);
2634
2635 EXPECT_TRUE(channel_->SetCapturer(kSsrcs3[0], NULL));
2636 }
2637
TEST_F(WebRtcVideoChannel2Test,GetStatsTranslatesBandwidthLimitedResolutionCorrectly)2638 TEST_F(WebRtcVideoChannel2Test,
2639 GetStatsTranslatesBandwidthLimitedResolutionCorrectly) {
2640 FakeVideoSendStream* stream = AddSendStream();
2641 webrtc::VideoSendStream::Stats stats;
2642 stats.bw_limited_resolution = true;
2643 stream->SetStats(stats);
2644
2645 cricket::VideoMediaInfo info;
2646 EXPECT_TRUE(channel_->GetStats(&info));
2647 ASSERT_EQ(1U, info.senders.size());
2648 EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH,
2649 info.senders[0].adapt_reason);
2650 }
2651
TEST_F(WebRtcVideoChannel2Test,GetStatsTranslatesSendRtcpPacketTypesCorrectly)2652 TEST_F(WebRtcVideoChannel2Test,
2653 GetStatsTranslatesSendRtcpPacketTypesCorrectly) {
2654 FakeVideoSendStream* stream = AddSendStream();
2655 webrtc::VideoSendStream::Stats stats;
2656 stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2;
2657 stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3;
2658 stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4;
2659
2660 stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5;
2661 stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7;
2662 stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9;
2663
2664 stream->SetStats(stats);
2665
2666 cricket::VideoMediaInfo info;
2667 ASSERT_TRUE(channel_->GetStats(&info));
2668 EXPECT_EQ(7, info.senders[0].firs_rcvd);
2669 EXPECT_EQ(10, info.senders[0].nacks_rcvd);
2670 EXPECT_EQ(13, info.senders[0].plis_rcvd);
2671 }
2672
TEST_F(WebRtcVideoChannel2Test,GetStatsTranslatesReceiveRtcpPacketTypesCorrectly)2673 TEST_F(WebRtcVideoChannel2Test,
2674 GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) {
2675 FakeVideoReceiveStream* stream = AddRecvStream();
2676 webrtc::VideoReceiveStream::Stats stats;
2677 stats.rtcp_packet_type_counts.fir_packets = 2;
2678 stats.rtcp_packet_type_counts.nack_packets = 3;
2679 stats.rtcp_packet_type_counts.pli_packets = 4;
2680 stream->SetStats(stats);
2681
2682 cricket::VideoMediaInfo info;
2683 ASSERT_TRUE(channel_->GetStats(&info));
2684 EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets,
2685 info.receivers[0].firs_sent);
2686 EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets,
2687 info.receivers[0].nacks_sent);
2688 EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets,
2689 info.receivers[0].plis_sent);
2690 }
2691
TEST_F(WebRtcVideoChannel2Test,GetStatsTranslatesDecodeStatsCorrectly)2692 TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesDecodeStatsCorrectly) {
2693 FakeVideoReceiveStream* stream = AddRecvStream();
2694 webrtc::VideoReceiveStream::Stats stats;
2695 stats.decoder_implementation_name = "decoder_implementation_name";
2696 stats.decode_ms = 2;
2697 stats.max_decode_ms = 3;
2698 stats.current_delay_ms = 4;
2699 stats.target_delay_ms = 5;
2700 stats.jitter_buffer_ms = 6;
2701 stats.min_playout_delay_ms = 7;
2702 stats.render_delay_ms = 8;
2703 stream->SetStats(stats);
2704
2705 cricket::VideoMediaInfo info;
2706 ASSERT_TRUE(channel_->GetStats(&info));
2707 EXPECT_EQ(stats.decoder_implementation_name,
2708 info.receivers[0].decoder_implementation_name);
2709 EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
2710 EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
2711 EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
2712 EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
2713 EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
2714 EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
2715 EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
2716 }
2717
TEST_F(WebRtcVideoChannel2Test,GetStatsTranslatesReceivePacketStatsCorrectly)2718 TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesReceivePacketStatsCorrectly) {
2719 FakeVideoReceiveStream* stream = AddRecvStream();
2720 webrtc::VideoReceiveStream::Stats stats;
2721 stats.rtp_stats.transmitted.payload_bytes = 2;
2722 stats.rtp_stats.transmitted.header_bytes = 3;
2723 stats.rtp_stats.transmitted.padding_bytes = 4;
2724 stats.rtp_stats.transmitted.packets = 5;
2725 stats.rtcp_stats.cumulative_lost = 6;
2726 stats.rtcp_stats.fraction_lost = 7;
2727 stream->SetStats(stats);
2728
2729 cricket::VideoMediaInfo info;
2730 ASSERT_TRUE(channel_->GetStats(&info));
2731 EXPECT_EQ(stats.rtp_stats.transmitted.payload_bytes +
2732 stats.rtp_stats.transmitted.header_bytes +
2733 stats.rtp_stats.transmitted.padding_bytes,
2734 info.receivers[0].bytes_rcvd);
2735 EXPECT_EQ(stats.rtp_stats.transmitted.packets,
2736 info.receivers[0].packets_rcvd);
2737 EXPECT_EQ(stats.rtcp_stats.cumulative_lost, info.receivers[0].packets_lost);
2738 EXPECT_EQ(static_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8),
2739 info.receivers[0].fraction_lost);
2740 }
2741
TEST_F(WebRtcVideoChannel2Test,TranslatesCallStatsCorrectly)2742 TEST_F(WebRtcVideoChannel2Test, TranslatesCallStatsCorrectly) {
2743 AddSendStream();
2744 AddSendStream();
2745 webrtc::Call::Stats stats;
2746 stats.rtt_ms = 123;
2747 fake_call_->SetStats(stats);
2748
2749 cricket::VideoMediaInfo info;
2750 ASSERT_TRUE(channel_->GetStats(&info));
2751 ASSERT_EQ(2u, info.senders.size());
2752 EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms);
2753 EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
2754 }
2755
TEST_F(WebRtcVideoChannel2Test,TranslatesSenderBitrateStatsCorrectly)2756 TEST_F(WebRtcVideoChannel2Test, TranslatesSenderBitrateStatsCorrectly) {
2757 FakeVideoSendStream* stream = AddSendStream();
2758 webrtc::VideoSendStream::Stats stats;
2759 stats.target_media_bitrate_bps = 156;
2760 stats.media_bitrate_bps = 123;
2761 stats.substreams[17].total_bitrate_bps = 1;
2762 stats.substreams[17].retransmit_bitrate_bps = 2;
2763 stats.substreams[42].total_bitrate_bps = 3;
2764 stats.substreams[42].retransmit_bitrate_bps = 4;
2765 stream->SetStats(stats);
2766
2767 FakeVideoSendStream* stream2 = AddSendStream();
2768 webrtc::VideoSendStream::Stats stats2;
2769 stats2.target_media_bitrate_bps = 200;
2770 stats2.media_bitrate_bps = 321;
2771 stats2.substreams[13].total_bitrate_bps = 5;
2772 stats2.substreams[13].retransmit_bitrate_bps = 6;
2773 stats2.substreams[21].total_bitrate_bps = 7;
2774 stats2.substreams[21].retransmit_bitrate_bps = 8;
2775 stream2->SetStats(stats2);
2776
2777 cricket::VideoMediaInfo info;
2778 ASSERT_TRUE(channel_->GetStats(&info));
2779 ASSERT_EQ(2u, info.senders.size());
2780 // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
2781 // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
2782 EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate);
2783 EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate);
2784 EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
2785 info.bw_estimations[0].target_enc_bitrate);
2786 EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
2787 info.bw_estimations[0].actual_enc_bitrate);
2788 EXPECT_EQ(1 + 3 + 5 + 7, info.bw_estimations[0].transmit_bitrate)
2789 << "Bandwidth stats should take all streams into account.";
2790 EXPECT_EQ(2 + 4 + 6 + 8, info.bw_estimations[0].retransmit_bitrate)
2791 << "Bandwidth stats should take all streams into account.";
2792 }
2793
TEST_F(WebRtcVideoChannel2Test,DefaultReceiveStreamReconfiguresToUseRtx)2794 TEST_F(WebRtcVideoChannel2Test, DefaultReceiveStreamReconfiguresToUseRtx) {
2795 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2796
2797 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
2798 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
2799
2800 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
2801 const size_t kDataLength = 12;
2802 uint8_t data[kDataLength];
2803 memset(data, 0, sizeof(data));
2804 rtc::SetBE32(&data[8], ssrcs[0]);
2805 rtc::Buffer packet(data, kDataLength);
2806 rtc::PacketTime packet_time;
2807 channel_->OnPacketReceived(&packet, packet_time);
2808
2809 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
2810 << "No default receive stream created.";
2811 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
2812 EXPECT_EQ(0u, recv_stream->GetConfig().rtp.rtx.size())
2813 << "Default receive stream should not have configured RTX";
2814
2815 EXPECT_TRUE(channel_->AddRecvStream(
2816 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
2817 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
2818 << "AddRecvStream should've reconfigured, not added a new receiver.";
2819 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
2820 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size());
2821 EXPECT_EQ(rtx_ssrcs[0],
2822 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
2823 }
2824
TEST_F(WebRtcVideoChannel2Test,RejectsAddingStreamsWithMissingSsrcsForRtx)2825 TEST_F(WebRtcVideoChannel2Test, RejectsAddingStreamsWithMissingSsrcsForRtx) {
2826 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2827
2828 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
2829 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
2830
2831 StreamParams sp =
2832 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
2833 sp.ssrcs = ssrcs; // Without RTXs, this is the important part.
2834
2835 EXPECT_FALSE(channel_->AddSendStream(sp));
2836 EXPECT_FALSE(channel_->AddRecvStream(sp));
2837 }
2838
TEST_F(WebRtcVideoChannel2Test,RejectsAddingStreamsWithOverlappingRtxSsrcs)2839 TEST_F(WebRtcVideoChannel2Test, RejectsAddingStreamsWithOverlappingRtxSsrcs) {
2840 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2841
2842 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
2843 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
2844
2845 StreamParams sp =
2846 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
2847
2848 EXPECT_TRUE(channel_->AddSendStream(sp));
2849 EXPECT_TRUE(channel_->AddRecvStream(sp));
2850
2851 // The RTX SSRC is already used in previous streams, using it should fail.
2852 sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]);
2853 EXPECT_FALSE(channel_->AddSendStream(sp));
2854 EXPECT_FALSE(channel_->AddRecvStream(sp));
2855
2856 // After removing the original stream this should be fine to add (makes sure
2857 // that RTX ssrcs are not forever taken).
2858 EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0]));
2859 EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0]));
2860 EXPECT_TRUE(channel_->AddSendStream(sp));
2861 EXPECT_TRUE(channel_->AddRecvStream(sp));
2862 }
2863
TEST_F(WebRtcVideoChannel2Test,RejectsAddingStreamsWithOverlappingSimulcastSsrcs)2864 TEST_F(WebRtcVideoChannel2Test,
2865 RejectsAddingStreamsWithOverlappingSimulcastSsrcs) {
2866 static const uint32_t kFirstStreamSsrcs[] = {1, 2, 3};
2867 static const uint32_t kOverlappingStreamSsrcs[] = {4, 3, 5};
2868 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2869
2870 StreamParams sp =
2871 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs));
2872
2873 EXPECT_TRUE(channel_->AddSendStream(sp));
2874 EXPECT_TRUE(channel_->AddRecvStream(sp));
2875
2876 // One of the SSRCs is already used in previous streams, using it should fail.
2877 sp = cricket::CreateSimStreamParams("cname",
2878 MAKE_VECTOR(kOverlappingStreamSsrcs));
2879 EXPECT_FALSE(channel_->AddSendStream(sp));
2880 EXPECT_FALSE(channel_->AddRecvStream(sp));
2881
2882 // After removing the original stream this should be fine to add (makes sure
2883 // that RTX ssrcs are not forever taken).
2884 EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0]));
2885 EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0]));
2886 EXPECT_TRUE(channel_->AddSendStream(sp));
2887 EXPECT_TRUE(channel_->AddRecvStream(sp));
2888 }
2889
TEST_F(WebRtcVideoChannel2Test,ReportsSsrcGroupsInStats)2890 TEST_F(WebRtcVideoChannel2Test, ReportsSsrcGroupsInStats) {
2891 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2892
2893 static const uint32_t kSenderSsrcs[] = {4, 7, 10};
2894 static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11};
2895
2896 StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams(
2897 "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs));
2898
2899 EXPECT_TRUE(channel_->AddSendStream(sender_sp));
2900
2901 static const uint32_t kReceiverSsrcs[] = {3};
2902 static const uint32_t kReceiverRtxSsrcs[] = {2};
2903
2904 StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams(
2905 "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs));
2906 EXPECT_TRUE(channel_->AddRecvStream(receiver_sp));
2907
2908 cricket::VideoMediaInfo info;
2909 ASSERT_TRUE(channel_->GetStats(&info));
2910
2911 ASSERT_EQ(1u, info.senders.size());
2912 ASSERT_EQ(1u, info.receivers.size());
2913
2914 EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups);
2915 EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups);
2916 EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
2917 }
2918
TEST_F(WebRtcVideoChannel2Test,MapsReceivedPayloadTypeToCodecName)2919 TEST_F(WebRtcVideoChannel2Test, MapsReceivedPayloadTypeToCodecName) {
2920 FakeVideoReceiveStream* stream = AddRecvStream();
2921 webrtc::VideoReceiveStream::Stats stats;
2922 cricket::VideoMediaInfo info;
2923
2924 // Report no codec name before receiving.
2925 stream->SetStats(stats);
2926 ASSERT_TRUE(channel_->GetStats(&info));
2927 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
2928
2929 // Report VP8 if we're receiving it.
2930 stats.current_payload_type = kDefaultVp8PlType;
2931 stream->SetStats(stats);
2932 ASSERT_TRUE(channel_->GetStats(&info));
2933 EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());
2934
2935 // Report no codec name for unknown playload types.
2936 stats.current_payload_type = 3;
2937 stream->SetStats(stats);
2938 ASSERT_TRUE(channel_->GetStats(&info));
2939 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
2940 }
2941
TestReceiveUnsignalledSsrcPacket(uint8_t payload_type,bool expect_created_receive_stream)2942 void WebRtcVideoChannel2Test::TestReceiveUnsignalledSsrcPacket(
2943 uint8_t payload_type,
2944 bool expect_created_receive_stream) {
2945 // Add a RED RTX codec.
2946 VideoCodec red_rtx_codec =
2947 VideoCodec::CreateRtxCodec(kRedRtxPayloadType, kDefaultRedPlType);
2948 recv_parameters_.codecs.push_back(red_rtx_codec);
2949 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
2950
2951 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
2952 const size_t kDataLength = 12;
2953 uint8_t data[kDataLength];
2954 memset(data, 0, sizeof(data));
2955
2956 rtc::Set8(data, 1, payload_type);
2957 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
2958 rtc::Buffer packet(data, kDataLength);
2959 rtc::PacketTime packet_time;
2960 channel_->OnPacketReceived(&packet, packet_time);
2961
2962 if (expect_created_receive_stream) {
2963 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
2964 << "Should have created a receive stream for payload type: "
2965 << payload_type;
2966 } else {
2967 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size())
2968 << "Shouldn't have created a receive stream for payload type: "
2969 << payload_type;
2970 }
2971 }
2972
TEST_F(WebRtcVideoChannel2Test,Vp8PacketCreatesUnsignalledStream)2973 TEST_F(WebRtcVideoChannel2Test, Vp8PacketCreatesUnsignalledStream) {
2974 TestReceiveUnsignalledSsrcPacket(kDefaultVp8PlType, true);
2975 }
2976
TEST_F(WebRtcVideoChannel2Test,Vp9PacketCreatesUnsignalledStream)2977 TEST_F(WebRtcVideoChannel2Test, Vp9PacketCreatesUnsignalledStream) {
2978 TestReceiveUnsignalledSsrcPacket(kDefaultVp9PlType, true);
2979 }
2980
TEST_F(WebRtcVideoChannel2Test,RtxPacketDoesntCreateUnsignalledStream)2981 TEST_F(WebRtcVideoChannel2Test, RtxPacketDoesntCreateUnsignalledStream) {
2982 TestReceiveUnsignalledSsrcPacket(kDefaultRtxVp8PlType, false);
2983 }
2984
TEST_F(WebRtcVideoChannel2Test,UlpfecPacketDoesntCreateUnsignalledStream)2985 TEST_F(WebRtcVideoChannel2Test, UlpfecPacketDoesntCreateUnsignalledStream) {
2986 TestReceiveUnsignalledSsrcPacket(kDefaultUlpfecType, false);
2987 }
2988
TEST_F(WebRtcVideoChannel2Test,RedRtxPacketDoesntCreateUnsignalledStream)2989 TEST_F(WebRtcVideoChannel2Test, RedRtxPacketDoesntCreateUnsignalledStream) {
2990 TestReceiveUnsignalledSsrcPacket(kRedRtxPayloadType, false);
2991 }
2992
TestReceiverLocalSsrcConfiguration(bool receiver_first)2993 void WebRtcVideoChannel2Test::TestReceiverLocalSsrcConfiguration(
2994 bool receiver_first) {
2995 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2996
2997 const uint32_t kSenderSsrc = 0xC0FFEE;
2998 const uint32_t kSecondSenderSsrc = 0xBADCAFE;
2999 const uint32_t kReceiverSsrc = 0x4711;
3000 const uint32_t kExpectedDefaultReceiverSsrc = 1;
3001
3002 if (receiver_first) {
3003 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
3004 std::vector<FakeVideoReceiveStream*> receive_streams =
3005 fake_call_->GetVideoReceiveStreams();
3006 ASSERT_EQ(1u, receive_streams.size());
3007 // Default local SSRC when we have no sender.
3008 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
3009 receive_streams[0]->GetConfig().rtp.local_ssrc);
3010 }
3011 AddSendStream(StreamParams::CreateLegacy(kSenderSsrc));
3012 if (!receiver_first)
3013 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
3014 std::vector<FakeVideoReceiveStream*> receive_streams =
3015 fake_call_->GetVideoReceiveStreams();
3016 ASSERT_EQ(1u, receive_streams.size());
3017 EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
3018
3019 // Removing first sender should fall back to another (in this case the second)
3020 // local send stream's SSRC.
3021 AddSendStream(StreamParams::CreateLegacy(kSecondSenderSsrc));
3022 ASSERT_TRUE(channel_->RemoveSendStream(kSenderSsrc));
3023 receive_streams =
3024 fake_call_->GetVideoReceiveStreams();
3025 ASSERT_EQ(1u, receive_streams.size());
3026 EXPECT_EQ(kSecondSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
3027
3028 // Removing the last sender should fall back to default local SSRC.
3029 ASSERT_TRUE(channel_->RemoveSendStream(kSecondSenderSsrc));
3030 receive_streams =
3031 fake_call_->GetVideoReceiveStreams();
3032 ASSERT_EQ(1u, receive_streams.size());
3033 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
3034 receive_streams[0]->GetConfig().rtp.local_ssrc);
3035 }
3036
TEST_F(WebRtcVideoChannel2Test,ConfiguresLocalSsrc)3037 TEST_F(WebRtcVideoChannel2Test, ConfiguresLocalSsrc) {
3038 TestReceiverLocalSsrcConfiguration(false);
3039 }
3040
TEST_F(WebRtcVideoChannel2Test,ConfiguresLocalSsrcOnExistingReceivers)3041 TEST_F(WebRtcVideoChannel2Test, ConfiguresLocalSsrcOnExistingReceivers) {
3042 TestReceiverLocalSsrcConfiguration(true);
3043 }
3044
3045 class WebRtcVideoEngine2SimulcastTest : public testing::Test {};
3046
3047 // Test that if we add a stream with RTX SSRC's, SSRC's get set correctly.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_TestStreamWithRtx)3048 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_TestStreamWithRtx) {
3049 // TODO(pbos): Implement.
3050 FAIL() << "Not implemented.";
3051 }
3052
3053 // Test that if we get too few ssrcs are given in AddSendStream(),
3054 // only supported sub-streams will be added.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_TooFewSimulcastSsrcs)3055 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_TooFewSimulcastSsrcs) {
3056 // TODO(pbos): Implement.
3057 FAIL() << "Not implemented.";
3058 }
3059
3060 // Test that even more than enough ssrcs are given in AddSendStream(),
3061 // only supported sub-streams will be added.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_MoreThanEnoughSimulcastSscrs)3062 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_MoreThanEnoughSimulcastSscrs) {
3063 // TODO(pbos): Implement.
3064 FAIL() << "Not implemented.";
3065 }
3066
3067 // Test that SetSendStreamFormat works well with simulcast.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_SetSendStreamFormatWithSimulcast)3068 TEST_F(WebRtcVideoEngine2SimulcastTest,
3069 DISABLED_SetSendStreamFormatWithSimulcast) {
3070 // TODO(pbos): Implement.
3071 FAIL() << "Not implemented.";
3072 }
3073
3074 // Test that simulcast send codec is reset on new video frame size.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_ResetSimulcastSendCodecOnNewFrameSize)3075 TEST_F(WebRtcVideoEngine2SimulcastTest,
3076 DISABLED_ResetSimulcastSendCodecOnNewFrameSize) {
3077 // TODO(pbos): Implement.
3078 FAIL() << "Not implemented.";
3079 }
3080
3081 // Test that simulcast send codec is reset on new portait mode video frame.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_ResetSimulcastSendCodecOnNewPortaitFrame)3082 TEST_F(WebRtcVideoEngine2SimulcastTest,
3083 DISABLED_ResetSimulcastSendCodecOnNewPortaitFrame) {
3084 // TODO(pbos): Implement.
3085 FAIL() << "Not implemented.";
3086 }
3087
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_SetBandwidthInConferenceWithSimulcast)3088 TEST_F(WebRtcVideoEngine2SimulcastTest,
3089 DISABLED_SetBandwidthInConferenceWithSimulcast) {
3090 // TODO(pbos): Implement.
3091 FAIL() << "Not implemented.";
3092 }
3093
3094 // Test that sending screencast frames in conference mode changes
3095 // bitrate.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_SetBandwidthScreencastInConference)3096 TEST_F(WebRtcVideoEngine2SimulcastTest,
3097 DISABLED_SetBandwidthScreencastInConference) {
3098 // TODO(pbos): Implement.
3099 FAIL() << "Not implemented.";
3100 }
3101
3102 // Test AddSendStream with simulcast rejects bad StreamParams.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_AddSendStreamWithBadStreamParams)3103 TEST_F(WebRtcVideoEngine2SimulcastTest,
3104 DISABLED_AddSendStreamWithBadStreamParams) {
3105 // TODO(pbos): Implement.
3106 FAIL() << "Not implemented.";
3107 }
3108
3109 // Test AddSendStream with simulcast sets ssrc and cname correctly.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_AddSendStreamWithSimulcast)3110 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_AddSendStreamWithSimulcast) {
3111 // TODO(pbos): Implement.
3112 FAIL() << "Not implemented.";
3113 }
3114
3115 // Test RemoveSendStream with simulcast.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_RemoveSendStreamWithSimulcast)3116 TEST_F(WebRtcVideoEngine2SimulcastTest,
3117 DISABLED_RemoveSendStreamWithSimulcast) {
3118 // TODO(pbos): Implement.
3119 FAIL() << "Not implemented.";
3120 }
3121
3122 // Test AddSendStream after send codec has already been set will reset
3123 // send codec with simulcast settings.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_AddSimulcastStreamAfterSetSendCodec)3124 TEST_F(WebRtcVideoEngine2SimulcastTest,
3125 DISABLED_AddSimulcastStreamAfterSetSendCodec) {
3126 // TODO(pbos): Implement.
3127 FAIL() << "Not implemented.";
3128 }
3129
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_GetStatsWithMultipleSsrcs)3130 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_GetStatsWithMultipleSsrcs) {
3131 // TODO(pbos): Implement.
3132 FAIL() << "Not implemented.";
3133 }
3134
3135 // Test receiving channel(s) local ssrc is set to the same as the first
3136 // simulcast sending ssrc.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_AddSimulcastStreamAfterCreatingRecvChannels)3137 TEST_F(WebRtcVideoEngine2SimulcastTest,
3138 DISABLED_AddSimulcastStreamAfterCreatingRecvChannels) {
3139 // TODO(pbos): Implement.
3140 FAIL() << "Not implemented.";
3141 }
3142
3143 // Test 1:1 call never turn on simulcast.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_NoSimulcastWith1on1)3144 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_NoSimulcastWith1on1) {
3145 // TODO(pbos): Implement.
3146 FAIL() << "Not implemented.";
3147 }
3148
3149 // Test SetOptions with OPT_CONFERENCE flag.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_SetOptionsWithConferenceMode)3150 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_SetOptionsWithConferenceMode) {
3151 // TODO(pbos): Implement.
3152 FAIL() << "Not implemented.";
3153 }
3154
3155 // Test that two different streams can have different formats.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_MultipleSendStreamsDifferentFormats)3156 TEST_F(WebRtcVideoEngine2SimulcastTest,
3157 DISABLED_MultipleSendStreamsDifferentFormats) {
3158 // TODO(pbos): Implement.
3159 FAIL() << "Not implemented.";
3160 }
3161
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_TestAdaptToOutputFormat)3162 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_TestAdaptToOutputFormat) {
3163 // TODO(pbos): Implement.
3164 FAIL() << "Not implemented.";
3165 }
3166
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_TestAdaptWithCpuOveruseObserver)3167 TEST_F(WebRtcVideoEngine2SimulcastTest,
3168 DISABLED_TestAdaptWithCpuOveruseObserver) {
3169 // TODO(pbos): Implement.
3170 FAIL() << "Not implemented.";
3171 }
3172
3173 // Test that codec is not reset for every frame sent in non-conference and
3174 // non-screencast mode.
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_DontResetCodecOnSendFrame)3175 TEST_F(WebRtcVideoEngine2SimulcastTest, DISABLED_DontResetCodecOnSendFrame) {
3176 // TODO(pbos): Implement.
3177 FAIL() << "Not implemented.";
3178 }
3179
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_UseSimulcastAdapterOnVp8OnlyFactory)3180 TEST_F(WebRtcVideoEngine2SimulcastTest,
3181 DISABLED_UseSimulcastAdapterOnVp8OnlyFactory) {
3182 // TODO(pbos): Implement.
3183 FAIL() << "Not implemented.";
3184 }
3185
TEST_F(WebRtcVideoEngine2SimulcastTest,DISABLED_DontUseSimulcastAdapterOnNonVp8Factory)3186 TEST_F(WebRtcVideoEngine2SimulcastTest,
3187 DISABLED_DontUseSimulcastAdapterOnNonVp8Factory) {
3188 // TODO(pbos): Implement.
3189 FAIL() << "Not implemented.";
3190 }
3191
3192 class WebRtcVideoChannel2SimulcastTest : public testing::Test {
3193 public:
WebRtcVideoChannel2SimulcastTest()3194 WebRtcVideoChannel2SimulcastTest() : fake_call_(webrtc::Call::Config()) {}
3195
SetUp()3196 void SetUp() override {
3197 engine_.Init();
3198 channel_.reset(engine_.CreateChannel(&fake_call_, VideoOptions()));
3199 last_ssrc_ = 123;
3200 }
3201
3202 protected:
VerifySimulcastSettings(const VideoCodec & codec,size_t num_configured_streams,size_t expected_num_streams)3203 void VerifySimulcastSettings(const VideoCodec& codec,
3204 size_t num_configured_streams,
3205 size_t expected_num_streams) {
3206 cricket::VideoSendParameters parameters;
3207 parameters.codecs.push_back(codec);
3208 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3209
3210 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3211 RTC_DCHECK(num_configured_streams <= ssrcs.size());
3212 ssrcs.resize(num_configured_streams);
3213
3214 FakeVideoSendStream* stream =
3215 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3216 // Send a full-size frame to trigger a stream reconfiguration to use all
3217 // expected simulcast layers.
3218 cricket::FakeVideoCapturer capturer;
3219 EXPECT_TRUE(channel_->SetCapturer(ssrcs.front(), &capturer));
3220 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(cricket::VideoFormat(
3221 codec.width, codec.height,
3222 cricket::VideoFormat::FpsToInterval(30),
3223 cricket::FOURCC_I420)));
3224 channel_->SetSend(true);
3225 EXPECT_TRUE(capturer.CaptureFrame());
3226
3227 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
3228 ASSERT_EQ(expected_num_streams, video_streams.size());
3229
3230 std::vector<webrtc::VideoStream> expected_streams = GetSimulcastConfig(
3231 num_configured_streams, codec.width, codec.height, 0, kDefaultQpMax,
3232 codec.framerate != 0 ? codec.framerate : kDefaultFramerate);
3233
3234 ASSERT_EQ(expected_streams.size(), video_streams.size());
3235
3236 size_t num_streams = video_streams.size();
3237 int total_max_bitrate_bps = 0;
3238 for (size_t i = 0; i < num_streams; ++i) {
3239 EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
3240 EXPECT_EQ(expected_streams[i].height, video_streams[i].height);
3241
3242 EXPECT_GT(video_streams[i].max_framerate, 0);
3243 EXPECT_EQ(expected_streams[i].max_framerate,
3244 video_streams[i].max_framerate);
3245
3246 EXPECT_GT(video_streams[i].min_bitrate_bps, 0);
3247 EXPECT_EQ(expected_streams[i].min_bitrate_bps,
3248 video_streams[i].min_bitrate_bps);
3249
3250 EXPECT_GT(video_streams[i].target_bitrate_bps, 0);
3251 EXPECT_EQ(expected_streams[i].target_bitrate_bps,
3252 video_streams[i].target_bitrate_bps);
3253
3254 EXPECT_GT(video_streams[i].max_bitrate_bps, 0);
3255 EXPECT_EQ(expected_streams[i].max_bitrate_bps,
3256 video_streams[i].max_bitrate_bps);
3257
3258 EXPECT_GT(video_streams[i].max_qp, 0);
3259 EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp);
3260
3261 EXPECT_FALSE(expected_streams[i].temporal_layer_thresholds_bps.empty());
3262 EXPECT_EQ(expected_streams[i].temporal_layer_thresholds_bps,
3263 video_streams[i].temporal_layer_thresholds_bps);
3264
3265 if (i == num_streams - 1) {
3266 total_max_bitrate_bps += video_streams[i].max_bitrate_bps;
3267 } else {
3268 total_max_bitrate_bps += video_streams[i].target_bitrate_bps;
3269 }
3270 }
3271 cricket::VideoMediaInfo info;
3272 ASSERT_TRUE(channel_->GetStats(&info));
3273 ASSERT_EQ(1u, info.senders.size());
3274 EXPECT_EQ(total_max_bitrate_bps, info.senders[0].preferred_bitrate);
3275
3276 EXPECT_TRUE(channel_->SetCapturer(ssrcs.front(), NULL));
3277 }
3278
AddSendStream()3279 FakeVideoSendStream* AddSendStream() {
3280 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++));
3281 }
3282
AddSendStream(const StreamParams & sp)3283 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
3284 size_t num_streams =
3285 fake_call_.GetVideoSendStreams().size();
3286 EXPECT_TRUE(channel_->AddSendStream(sp));
3287 std::vector<FakeVideoSendStream*> streams =
3288 fake_call_.GetVideoSendStreams();
3289 EXPECT_EQ(num_streams + 1, streams.size());
3290 return streams[streams.size() - 1];
3291 }
3292
GetFakeSendStreams()3293 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
3294 return fake_call_.GetVideoSendStreams();
3295 }
3296
AddRecvStream()3297 FakeVideoReceiveStream* AddRecvStream() {
3298 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++));
3299 }
3300
AddRecvStream(const StreamParams & sp)3301 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
3302 size_t num_streams =
3303 fake_call_.GetVideoReceiveStreams().size();
3304 EXPECT_TRUE(channel_->AddRecvStream(sp));
3305 std::vector<FakeVideoReceiveStream*> streams =
3306 fake_call_.GetVideoReceiveStreams();
3307 EXPECT_EQ(num_streams + 1, streams.size());
3308 return streams[streams.size() - 1];
3309 }
3310
3311 FakeCall fake_call_;
3312 WebRtcVideoEngine2 engine_;
3313 rtc::scoped_ptr<VideoMediaChannel> channel_;
3314 uint32_t last_ssrc_;
3315 };
3316
TEST_F(WebRtcVideoChannel2SimulcastTest,SetSendCodecsWith2SimulcastStreams)3317 TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith2SimulcastStreams) {
3318 VerifySimulcastSettings(kVp8Codec, 2, 2);
3319 }
3320
TEST_F(WebRtcVideoChannel2SimulcastTest,SetSendCodecsWith3SimulcastStreams)3321 TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWith3SimulcastStreams) {
3322 VerifySimulcastSettings(kVp8Codec720p, 3, 3);
3323 }
3324
3325 // Test that we normalize send codec format size in simulcast.
TEST_F(WebRtcVideoChannel2SimulcastTest,SetSendCodecsWithOddSizeInSimulcast)3326 TEST_F(WebRtcVideoChannel2SimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
3327 cricket::VideoCodec codec(kVp8Codec270p);
3328 codec.width += 1;
3329 codec.height += 1;
3330 VerifySimulcastSettings(codec, 2, 2);
3331 }
3332
TEST_F(WebRtcVideoChannel2SimulcastTest,DISABLED_SimulcastSend_1280x800)3333 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_1280x800) {
3334 // TODO(pbos): Implement.
3335 FAIL() << "Not implemented.";
3336 }
3337
TEST_F(WebRtcVideoChannel2SimulcastTest,DISABLED_SimulcastSend_1280x720)3338 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_1280x720) {
3339 // TODO(pbos): Implement.
3340 FAIL() << "Not implemented.";
3341 }
3342
TEST_F(WebRtcVideoChannel2SimulcastTest,DISABLED_SimulcastSend_960x540)3343 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_960x540) {
3344 // TODO(pbos): Implement.
3345 FAIL() << "Not implemented.";
3346 }
3347
TEST_F(WebRtcVideoChannel2SimulcastTest,DISABLED_SimulcastSend_960x600)3348 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_960x600) {
3349 // TODO(pbos): Implement.
3350 FAIL() << "Not implemented.";
3351 }
3352
TEST_F(WebRtcVideoChannel2SimulcastTest,DISABLED_SimulcastSend_640x400)3353 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_640x400) {
3354 // TODO(pbos): Implement.
3355 FAIL() << "Not implemented.";
3356 }
3357
TEST_F(WebRtcVideoChannel2SimulcastTest,DISABLED_SimulcastSend_640x360)3358 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_640x360) {
3359 // TODO(pbos): Implement.
3360 FAIL() << "Not implemented.";
3361 }
3362
TEST_F(WebRtcVideoChannel2SimulcastTest,DISABLED_SimulcastSend_480x300)3363 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_480x300) {
3364 // TODO(pbos): Implement.
3365 FAIL() << "Not implemented.";
3366 }
3367
TEST_F(WebRtcVideoChannel2SimulcastTest,DISABLED_SimulcastSend_480x270)3368 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_480x270) {
3369 // TODO(pbos): Implement.
3370 FAIL() << "Not implemented.";
3371 }
3372
TEST_F(WebRtcVideoChannel2SimulcastTest,DISABLED_SimulcastSend_320x200)3373 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_320x200) {
3374 // TODO(pbos): Implement.
3375 FAIL() << "Not implemented.";
3376 }
3377
TEST_F(WebRtcVideoChannel2SimulcastTest,DISABLED_SimulcastSend_320x180)3378 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastSend_320x180) {
3379 // TODO(pbos): Implement.
3380 FAIL() << "Not implemented.";
3381 }
3382
3383 // Test simulcast streams are decodeable with expected sizes.
TEST_F(WebRtcVideoChannel2SimulcastTest,DISABLED_SimulcastStreams)3384 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_SimulcastStreams) {
3385 // TODO(pbos): Implement.
3386 FAIL() << "Not implemented.";
3387 }
3388
3389 // Simulcast and resolution resizing should be turned off when screencasting
3390 // but not otherwise.
TEST_F(WebRtcVideoChannel2SimulcastTest,DISABLED_ScreencastRendering)3391 TEST_F(WebRtcVideoChannel2SimulcastTest, DISABLED_ScreencastRendering) {
3392 // TODO(pbos): Implement.
3393 FAIL() << "Not implemented.";
3394 }
3395
3396 // Ensures that the correct settings are applied to the codec when single
3397 // temporal layer screencasting is enabled, and that the correct simulcast
3398 // settings are reapplied when disabling screencasting.
TEST_F(WebRtcVideoChannel2SimulcastTest,DISABLED_OneTemporalLayerScreencastSettings)3399 TEST_F(WebRtcVideoChannel2SimulcastTest,
3400 DISABLED_OneTemporalLayerScreencastSettings) {
3401 // TODO(pbos): Implement.
3402 FAIL() << "Not implemented.";
3403 }
3404
3405 // Ensures that the correct settings are applied to the codec when two temporal
3406 // layer screencasting is enabled, and that the correct simulcast settings are
3407 // reapplied when disabling screencasting.
TEST_F(WebRtcVideoChannel2SimulcastTest,DISABLED_TwoTemporalLayerScreencastSettings)3408 TEST_F(WebRtcVideoChannel2SimulcastTest,
3409 DISABLED_TwoTemporalLayerScreencastSettings) {
3410 // TODO(pbos): Implement.
3411 FAIL() << "Not implemented.";
3412 }
3413
3414 } // namespace cricket
3415