1 /*
2 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "media/engine/webrtc_video_engine.h"
12
13 #include <map>
14 #include <memory>
15 #include <string>
16 #include <utility>
17 #include <vector>
18
19 #include "absl/algorithm/container.h"
20 #include "absl/memory/memory.h"
21 #include "absl/strings/match.h"
22 #include "api/rtc_event_log/rtc_event_log.h"
23 #include "api/rtp_parameters.h"
24 #include "api/task_queue/default_task_queue_factory.h"
25 #include "api/test/mock_video_bitrate_allocator.h"
26 #include "api/test/mock_video_bitrate_allocator_factory.h"
27 #include "api/test/mock_video_decoder_factory.h"
28 #include "api/test/mock_video_encoder_factory.h"
29 #include "api/test/video/function_video_decoder_factory.h"
30 #include "api/transport/field_trial_based_config.h"
31 #include "api/units/time_delta.h"
32 #include "api/video/builtin_video_bitrate_allocator_factory.h"
33 #include "api/video/i420_buffer.h"
34 #include "api/video/video_bitrate_allocation.h"
35 #include "api/video_codecs/builtin_video_decoder_factory.h"
36 #include "api/video_codecs/builtin_video_encoder_factory.h"
37 #include "api/video_codecs/sdp_video_format.h"
38 #include "api/video_codecs/video_decoder_factory.h"
39 #include "api/video_codecs/video_encoder.h"
40 #include "api/video_codecs/video_encoder_factory.h"
41 #include "call/flexfec_receive_stream.h"
42 #include "common_video/h264/profile_level_id.h"
43 #include "media/base/fake_frame_source.h"
44 #include "media/base/fake_network_interface.h"
45 #include "media/base/fake_video_renderer.h"
46 #include "media/base/media_constants.h"
47 #include "media/base/rtp_utils.h"
48 #include "media/base/test_utils.h"
49 #include "media/engine/constants.h"
50 #include "media/engine/fake_webrtc_call.h"
51 #include "media/engine/fake_webrtc_video_engine.h"
52 #include "media/engine/simulcast.h"
53 #include "media/engine/webrtc_voice_engine.h"
54 #include "rtc_base/arraysize.h"
55 #include "rtc_base/experiments/min_video_bitrate_experiment.h"
56 #include "rtc_base/fake_clock.h"
57 #include "rtc_base/gunit.h"
58 #include "rtc_base/numerics/safe_conversions.h"
59 #include "rtc_base/time_utils.h"
60 #include "test/fake_decoder.h"
61 #include "test/field_trial.h"
62 #include "test/frame_forwarder.h"
63 #include "test/gmock.h"
64 #include "test/rtp_header_parser.h"
65
66 using ::testing::_;
67 using ::testing::Contains;
68 using ::testing::Each;
69 using ::testing::ElementsAreArray;
70 using ::testing::Eq;
71 using ::testing::Field;
72 using ::testing::IsEmpty;
73 using ::testing::Pair;
74 using ::testing::Return;
75 using ::testing::SizeIs;
76 using ::testing::StrNe;
77 using ::testing::Values;
78 using webrtc::BitrateConstraints;
79 using webrtc::RtpExtension;
80
81 namespace {
82 static const int kDefaultQpMax = 56;
83
84 static const uint8_t kRedRtxPayloadType = 125;
85
86 static const uint32_t kTimeout = 5000U;
87 static const uint32_t kSsrc = 1234u;
88 static const uint32_t kSsrcs4[] = {1, 2, 3, 4};
89 static const int kVideoWidth = 640;
90 static const int kVideoHeight = 360;
91 static const int kFramerate = 30;
92
93 static const uint32_t kSsrcs1[] = {1};
94 static const uint32_t kSsrcs3[] = {1, 2, 3};
95 static const uint32_t kRtxSsrcs1[] = {4};
96 static const uint32_t kFlexfecSsrc = 5;
97 static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE;
98
99 constexpr uint32_t kRtpHeaderSize = 12;
100
101 static const char kUnsupportedExtensionName[] =
102 "urn:ietf:params:rtp-hdrext:unsupported";
103
RemoveFeedbackParams(cricket::VideoCodec && codec)104 cricket::VideoCodec RemoveFeedbackParams(cricket::VideoCodec&& codec) {
105 codec.feedback_params = cricket::FeedbackParams();
106 return std::move(codec);
107 }
108
VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec & codec,bool lntf_expected)109 void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec,
110 bool lntf_expected) {
111 EXPECT_EQ(lntf_expected,
112 codec.HasFeedbackParam(cricket::FeedbackParam(
113 cricket::kRtcpFbParamLntf, cricket::kParamValueEmpty)));
114 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
115 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
116 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
117 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
118 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
119 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
120 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
121 cricket::kRtcpFbParamTransportCc, cricket::kParamValueEmpty)));
122 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
123 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
124 }
125
126 // Return true if any codec in |codecs| is an RTX codec with associated payload
127 // type |payload_type|.
HasRtxCodec(const std::vector<cricket::VideoCodec> & codecs,int payload_type)128 bool HasRtxCodec(const std::vector<cricket::VideoCodec>& codecs,
129 int payload_type) {
130 for (const cricket::VideoCodec& codec : codecs) {
131 int associated_payload_type;
132 if (absl::EqualsIgnoreCase(codec.name.c_str(), "rtx") &&
133 codec.GetParam(cricket::kCodecParamAssociatedPayloadType,
134 &associated_payload_type) &&
135 associated_payload_type == payload_type) {
136 return true;
137 }
138 }
139 return false;
140 }
141
142 // TODO(nisse): Duplicated in call.cc.
FindKeyByValue(const std::map<int,int> & m,int v)143 const int* FindKeyByValue(const std::map<int, int>& m, int v) {
144 for (const auto& kv : m) {
145 if (kv.second == v)
146 return &kv.first;
147 }
148 return nullptr;
149 }
150
HasRtxReceiveAssociation(const webrtc::VideoReceiveStream::Config & config,int payload_type)151 bool HasRtxReceiveAssociation(const webrtc::VideoReceiveStream::Config& config,
152 int payload_type) {
153 return FindKeyByValue(config.rtp.rtx_associated_payload_types,
154 payload_type) != nullptr;
155 }
156
157 // Check that there's an Rtx payload type for each decoder.
VerifyRtxReceiveAssociations(const webrtc::VideoReceiveStream::Config & config)158 bool VerifyRtxReceiveAssociations(
159 const webrtc::VideoReceiveStream::Config& config) {
160 for (const auto& decoder : config.decoders) {
161 if (!HasRtxReceiveAssociation(config, decoder.payload_type))
162 return false;
163 }
164 return true;
165 }
166
CreateBlackFrameBuffer(int width,int height)167 rtc::scoped_refptr<webrtc::VideoFrameBuffer> CreateBlackFrameBuffer(
168 int width,
169 int height) {
170 rtc::scoped_refptr<webrtc::I420Buffer> buffer =
171 webrtc::I420Buffer::Create(width, height);
172 webrtc::I420Buffer::SetBlack(buffer);
173 return buffer;
174 }
175
VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config & config,const std::map<int,int> & rtx_types)176 void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config,
177 const std::map<int, int>& rtx_types) {
178 std::map<int, int>::const_iterator it;
179 it = rtx_types.find(config.rtp.payload_type);
180 EXPECT_TRUE(it != rtx_types.end() &&
181 it->second == config.rtp.rtx.payload_type);
182
183 if (config.rtp.ulpfec.red_rtx_payload_type != -1) {
184 it = rtx_types.find(config.rtp.ulpfec.red_payload_type);
185 EXPECT_TRUE(it != rtx_types.end() &&
186 it->second == config.rtp.ulpfec.red_rtx_payload_type);
187 }
188 }
189
GetMediaConfig()190 cricket::MediaConfig GetMediaConfig() {
191 cricket::MediaConfig media_config;
192 media_config.video.enable_cpu_adaptation = false;
193 return media_config;
194 }
195
196 // Values from GetMaxDefaultVideoBitrateKbps in webrtcvideoengine.cc.
GetMaxDefaultBitrateBps(size_t width,size_t height)197 int GetMaxDefaultBitrateBps(size_t width, size_t height) {
198 if (width * height <= 320 * 240) {
199 return 600000;
200 } else if (width * height <= 640 * 480) {
201 return 1700000;
202 } else if (width * height <= 960 * 540) {
203 return 2000000;
204 } else {
205 return 2500000;
206 }
207 }
208
209 class MockVideoSource : public rtc::VideoSourceInterface<webrtc::VideoFrame> {
210 public:
211 MOCK_METHOD(void,
212 AddOrUpdateSink,
213 (rtc::VideoSinkInterface<webrtc::VideoFrame> * sink,
214 const rtc::VideoSinkWants& wants),
215 (override));
216 MOCK_METHOD(void,
217 RemoveSink,
218 (rtc::VideoSinkInterface<webrtc::VideoFrame> * sink),
219 (override));
220 };
221
222 } // namespace
223
224 #define EXPECT_FRAME_WAIT(c, w, h, t) \
225 EXPECT_EQ_WAIT((c), renderer_.num_rendered_frames(), (t)); \
226 EXPECT_EQ((w), renderer_.width()); \
227 EXPECT_EQ((h), renderer_.height()); \
228 EXPECT_EQ(0, renderer_.errors());
229
230 #define EXPECT_FRAME_ON_RENDERER_WAIT(r, c, w, h, t) \
231 EXPECT_EQ_WAIT((c), (r).num_rendered_frames(), (t)); \
232 EXPECT_EQ((w), (r).width()); \
233 EXPECT_EQ((h), (r).height()); \
234 EXPECT_EQ(0, (r).errors());
235
236 namespace cricket {
237 class WebRtcVideoEngineTest : public ::testing::Test {
238 public:
WebRtcVideoEngineTest()239 WebRtcVideoEngineTest() : WebRtcVideoEngineTest("") {}
WebRtcVideoEngineTest(const std::string & field_trials)240 explicit WebRtcVideoEngineTest(const std::string& field_trials)
241 : override_field_trials_(
242 field_trials.empty()
243 ? nullptr
244 : std::make_unique<webrtc::test::ScopedFieldTrials>(
245 field_trials)),
246 task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
247 call_(webrtc::Call::Create([&] {
248 webrtc::Call::Config call_config(&event_log_);
249 call_config.task_queue_factory = task_queue_factory_.get();
250 call_config.trials = &field_trials_;
251 return call_config;
252 }())),
253 encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
254 decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
255 video_bitrate_allocator_factory_(
256 webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
257 engine_(std::unique_ptr<cricket::FakeWebRtcVideoEncoderFactory>(
258 encoder_factory_),
259 std::unique_ptr<cricket::FakeWebRtcVideoDecoderFactory>(
260 decoder_factory_)) {
261 // Ensure fake clock doesn't return 0, which will cause some initializations
262 // fail inside RTP senders.
263 fake_clock_.AdvanceTime(webrtc::TimeDelta::Micros(1));
264 }
265
266 protected:
267 void AssignDefaultAptRtxTypes();
268 void AssignDefaultCodec();
269
270 // Find the index of the codec in the engine with the given name. The codec
271 // must be present.
272 size_t GetEngineCodecIndex(const std::string& name) const;
273
274 // Find the codec in the engine with the given name. The codec must be
275 // present.
276 cricket::VideoCodec GetEngineCodec(const std::string& name) const;
277 void AddSupportedVideoCodecType(const std::string& name);
278 VideoMediaChannel* SetSendParamsWithAllSupportedCodecs();
279
280 VideoMediaChannel* SetRecvParamsWithSupportedCodecs(
281 const std::vector<VideoCodec>& codecs);
282
283 void ExpectRtpCapabilitySupport(const char* uri, bool supported) const;
284
285 // Has to be the first one, so it is initialized before the call or there is a
286 // race condition in the clock access.
287 rtc::ScopedFakeClock fake_clock_;
288 std::unique_ptr<webrtc::test::ScopedFieldTrials> override_field_trials_;
289 webrtc::FieldTrialBasedConfig field_trials_;
290 webrtc::RtcEventLogNull event_log_;
291 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
292 // Used in WebRtcVideoEngineVoiceTest, but defined here so it's properly
293 // initialized when the constructor is called.
294 std::unique_ptr<webrtc::Call> call_;
295 cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
296 cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
297 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
298 video_bitrate_allocator_factory_;
299 WebRtcVideoEngine engine_;
300 VideoCodec default_codec_;
301 std::map<int, int> default_apt_rtx_types_;
302 };
303
TEST_F(WebRtcVideoEngineTest,DefaultRtxCodecHasAssociatedPayloadTypeSet)304 TEST_F(WebRtcVideoEngineTest, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
305 encoder_factory_->AddSupportedVideoCodecType("VP8");
306 AssignDefaultCodec();
307
308 std::vector<VideoCodec> engine_codecs = engine_.send_codecs();
309 for (size_t i = 0; i < engine_codecs.size(); ++i) {
310 if (engine_codecs[i].name != kRtxCodecName)
311 continue;
312 int associated_payload_type;
313 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
314 &associated_payload_type));
315 EXPECT_EQ(default_codec_.id, associated_payload_type);
316 return;
317 }
318 FAIL() << "No RTX codec found among default codecs.";
319 }
320
TEST_F(WebRtcVideoEngineTest,SupportsTimestampOffsetHeaderExtension)321 TEST_F(WebRtcVideoEngineTest, SupportsTimestampOffsetHeaderExtension) {
322 ExpectRtpCapabilitySupport(RtpExtension::kTimestampOffsetUri, true);
323 }
324
TEST_F(WebRtcVideoEngineTest,SupportsAbsoluteSenderTimeHeaderExtension)325 TEST_F(WebRtcVideoEngineTest, SupportsAbsoluteSenderTimeHeaderExtension) {
326 ExpectRtpCapabilitySupport(RtpExtension::kAbsSendTimeUri, true);
327 }
328
TEST_F(WebRtcVideoEngineTest,SupportsTransportSequenceNumberHeaderExtension)329 TEST_F(WebRtcVideoEngineTest, SupportsTransportSequenceNumberHeaderExtension) {
330 ExpectRtpCapabilitySupport(RtpExtension::kTransportSequenceNumberUri, true);
331 }
332
TEST_F(WebRtcVideoEngineTest,SupportsVideoRotationHeaderExtension)333 TEST_F(WebRtcVideoEngineTest, SupportsVideoRotationHeaderExtension) {
334 ExpectRtpCapabilitySupport(RtpExtension::kVideoRotationUri, true);
335 }
336
TEST_F(WebRtcVideoEngineTest,SupportsPlayoutDelayHeaderExtension)337 TEST_F(WebRtcVideoEngineTest, SupportsPlayoutDelayHeaderExtension) {
338 ExpectRtpCapabilitySupport(RtpExtension::kPlayoutDelayUri, true);
339 }
340
TEST_F(WebRtcVideoEngineTest,SupportsVideoContentTypeHeaderExtension)341 TEST_F(WebRtcVideoEngineTest, SupportsVideoContentTypeHeaderExtension) {
342 ExpectRtpCapabilitySupport(RtpExtension::kVideoContentTypeUri, true);
343 }
344
TEST_F(WebRtcVideoEngineTest,SupportsVideoTimingHeaderExtension)345 TEST_F(WebRtcVideoEngineTest, SupportsVideoTimingHeaderExtension) {
346 ExpectRtpCapabilitySupport(RtpExtension::kVideoTimingUri, true);
347 }
348
TEST_F(WebRtcVideoEngineTest,SupportsColorSpaceHeaderExtension)349 TEST_F(WebRtcVideoEngineTest, SupportsColorSpaceHeaderExtension) {
350 ExpectRtpCapabilitySupport(RtpExtension::kColorSpaceUri, true);
351 }
352
TEST_F(WebRtcVideoEngineTest,AdvertiseGenericDescriptor00)353 TEST_F(WebRtcVideoEngineTest, AdvertiseGenericDescriptor00) {
354 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri00, false);
355 }
356
357 class WebRtcVideoEngineTestWithGenericDescriptor
358 : public WebRtcVideoEngineTest {
359 public:
WebRtcVideoEngineTestWithGenericDescriptor()360 WebRtcVideoEngineTestWithGenericDescriptor()
361 : WebRtcVideoEngineTest("WebRTC-GenericDescriptorAdvertised/Enabled/") {}
362 };
363
TEST_F(WebRtcVideoEngineTestWithGenericDescriptor,AdvertiseGenericDescriptor00)364 TEST_F(WebRtcVideoEngineTestWithGenericDescriptor,
365 AdvertiseGenericDescriptor00) {
366 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri00, true);
367 }
368
TEST_F(WebRtcVideoEngineTest,CVOSetHeaderExtensionBeforeCapturer)369 TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeCapturer) {
370 // Allocate the source first to prevent early destruction before channel's
371 // dtor is called.
372 ::testing::NiceMock<MockVideoSource> video_source;
373
374 AddSupportedVideoCodecType("VP8");
375
376 std::unique_ptr<VideoMediaChannel> channel(
377 SetSendParamsWithAllSupportedCodecs());
378 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
379
380 // Add CVO extension.
381 const int id = 1;
382 cricket::VideoSendParameters parameters;
383 parameters.codecs.push_back(GetEngineCodec("VP8"));
384 parameters.extensions.push_back(
385 RtpExtension(RtpExtension::kVideoRotationUri, id));
386 EXPECT_TRUE(channel->SetSendParameters(parameters));
387
388 EXPECT_CALL(
389 video_source,
390 AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, false)));
391 // Set capturer.
392 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
393
394 // Verify capturer has turned off applying rotation.
395 ::testing::Mock::VerifyAndClear(&video_source);
396
397 // Verify removing header extension turns on applying rotation.
398 parameters.extensions.clear();
399 EXPECT_CALL(
400 video_source,
401 AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, true)));
402
403 EXPECT_TRUE(channel->SetSendParameters(parameters));
404 }
405
TEST_F(WebRtcVideoEngineTest,CVOSetHeaderExtensionBeforeAddSendStream)406 TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeAddSendStream) {
407 // Allocate the source first to prevent early destruction before channel's
408 // dtor is called.
409 ::testing::NiceMock<MockVideoSource> video_source;
410
411 AddSupportedVideoCodecType("VP8");
412
413 std::unique_ptr<VideoMediaChannel> channel(
414 SetSendParamsWithAllSupportedCodecs());
415 // Add CVO extension.
416 const int id = 1;
417 cricket::VideoSendParameters parameters;
418 parameters.codecs.push_back(GetEngineCodec("VP8"));
419 parameters.extensions.push_back(
420 RtpExtension(RtpExtension::kVideoRotationUri, id));
421 EXPECT_TRUE(channel->SetSendParameters(parameters));
422 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
423
424 // Set source.
425 EXPECT_CALL(
426 video_source,
427 AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, false)));
428 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
429 }
430
TEST_F(WebRtcVideoEngineTest,CVOSetHeaderExtensionAfterCapturer)431 TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionAfterCapturer) {
432 ::testing::NiceMock<MockVideoSource> video_source;
433
434 AddSupportedVideoCodecType("VP8");
435 AddSupportedVideoCodecType("VP9");
436
437 std::unique_ptr<VideoMediaChannel> channel(
438 SetSendParamsWithAllSupportedCodecs());
439 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
440
441 // Set capturer.
442 EXPECT_CALL(
443 video_source,
444 AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, true)));
445 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
446
447 // Verify capturer has turned on applying rotation.
448 ::testing::Mock::VerifyAndClear(&video_source);
449
450 // Add CVO extension.
451 const int id = 1;
452 cricket::VideoSendParameters parameters;
453 parameters.codecs.push_back(GetEngineCodec("VP8"));
454 parameters.codecs.push_back(GetEngineCodec("VP9"));
455 parameters.extensions.push_back(
456 RtpExtension(RtpExtension::kVideoRotationUri, id));
457 // Also remove the first codec to trigger a codec change as well.
458 parameters.codecs.erase(parameters.codecs.begin());
459 EXPECT_CALL(
460 video_source,
461 AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, false)));
462 EXPECT_TRUE(channel->SetSendParameters(parameters));
463
464 // Verify capturer has turned off applying rotation.
465 ::testing::Mock::VerifyAndClear(&video_source);
466
467 // Verify removing header extension turns on applying rotation.
468 parameters.extensions.clear();
469 EXPECT_CALL(
470 video_source,
471 AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, true)));
472 EXPECT_TRUE(channel->SetSendParameters(parameters));
473 }
474
TEST_F(WebRtcVideoEngineTest,SetSendFailsBeforeSettingCodecs)475 TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) {
476 AddSupportedVideoCodecType("VP8");
477
478 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
479 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
480 video_bitrate_allocator_factory_.get()));
481
482 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
483
484 EXPECT_FALSE(channel->SetSend(true))
485 << "Channel should not start without codecs.";
486 EXPECT_TRUE(channel->SetSend(false))
487 << "Channel should be stoppable even without set codecs.";
488 }
489
TEST_F(WebRtcVideoEngineTest,GetStatsWithoutSendCodecsSetDoesNotCrash)490 TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) {
491 AddSupportedVideoCodecType("VP8");
492
493 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
494 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
495 video_bitrate_allocator_factory_.get()));
496 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
497 VideoMediaInfo info;
498 channel->GetStats(&info);
499 }
500
TEST_F(WebRtcVideoEngineTest,UseFactoryForVp8WhenSupported)501 TEST_F(WebRtcVideoEngineTest, UseFactoryForVp8WhenSupported) {
502 AddSupportedVideoCodecType("VP8");
503
504 std::unique_ptr<VideoMediaChannel> channel(
505 SetSendParamsWithAllSupportedCodecs());
506 channel->OnReadyToSend(true);
507
508 EXPECT_TRUE(
509 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
510 EXPECT_EQ(0, encoder_factory_->GetNumCreatedEncoders());
511 EXPECT_TRUE(channel->SetSend(true));
512 webrtc::test::FrameForwarder frame_forwarder;
513 cricket::FakeFrameSource frame_source(1280, 720,
514 rtc::kNumMicrosecsPerSec / 30);
515 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
516 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
517 // Sending one frame will have allocate the encoder.
518 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
519 EXPECT_TRUE_WAIT(encoder_factory_->encoders()[0]->GetNumEncodedFrames() > 0,
520 kTimeout);
521
522 int num_created_encoders = encoder_factory_->GetNumCreatedEncoders();
523 EXPECT_EQ(num_created_encoders, 1);
524
525 // Setting codecs of the same type should not reallocate any encoders
526 // (expecting a no-op).
527 cricket::VideoSendParameters parameters;
528 parameters.codecs.push_back(GetEngineCodec("VP8"));
529 EXPECT_TRUE(channel->SetSendParameters(parameters));
530 EXPECT_EQ(num_created_encoders, encoder_factory_->GetNumCreatedEncoders());
531
532 // Remove stream previously added to free the external encoder instance.
533 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
534 EXPECT_EQ(0u, encoder_factory_->encoders().size());
535 }
536
537 // Test that when an encoder factory supports H264, we add an RTX
538 // codec for it.
539 // TODO(deadbeef): This test should be updated if/when we start
540 // adding RTX codecs for unrecognized codec names.
TEST_F(WebRtcVideoEngineTest,RtxCodecAddedForH264Codec)541 TEST_F(WebRtcVideoEngineTest, RtxCodecAddedForH264Codec) {
542 using webrtc::H264::kLevel1;
543 using webrtc::H264::ProfileLevelId;
544 using webrtc::H264::ProfileLevelIdToString;
545 webrtc::SdpVideoFormat h264_constrained_baseline("H264");
546 h264_constrained_baseline.parameters[kH264FmtpProfileLevelId] =
547 *ProfileLevelIdToString(
548 ProfileLevelId(webrtc::H264::kProfileConstrainedBaseline, kLevel1));
549 webrtc::SdpVideoFormat h264_constrained_high("H264");
550 h264_constrained_high.parameters[kH264FmtpProfileLevelId] =
551 *ProfileLevelIdToString(
552 ProfileLevelId(webrtc::H264::kProfileConstrainedHigh, kLevel1));
553 webrtc::SdpVideoFormat h264_high("H264");
554 h264_high.parameters[kH264FmtpProfileLevelId] = *ProfileLevelIdToString(
555 ProfileLevelId(webrtc::H264::kProfileHigh, kLevel1));
556
557 encoder_factory_->AddSupportedVideoCodec(h264_constrained_baseline);
558 encoder_factory_->AddSupportedVideoCodec(h264_constrained_high);
559 encoder_factory_->AddSupportedVideoCodec(h264_high);
560
561 // First figure out what payload types the test codecs got assigned.
562 const std::vector<cricket::VideoCodec> codecs = engine_.send_codecs();
563 // Now search for RTX codecs for them. Expect that they all have associated
564 // RTX codecs.
565 EXPECT_TRUE(HasRtxCodec(
566 codecs,
567 FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_baseline))
568 ->id));
569 EXPECT_TRUE(HasRtxCodec(
570 codecs,
571 FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_high))
572 ->id));
573 EXPECT_TRUE(HasRtxCodec(
574 codecs, FindMatchingCodec(codecs, cricket::VideoCodec(h264_high))->id));
575 }
576
577 #if defined(RTC_ENABLE_VP9)
TEST_F(WebRtcVideoEngineTest,CanConstructDecoderForVp9EncoderFactory)578 TEST_F(WebRtcVideoEngineTest, CanConstructDecoderForVp9EncoderFactory) {
579 AddSupportedVideoCodecType("VP9");
580
581 std::unique_ptr<VideoMediaChannel> channel(
582 SetSendParamsWithAllSupportedCodecs());
583
584 EXPECT_TRUE(
585 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
586 }
587 #endif // defined(RTC_ENABLE_VP9)
588
TEST_F(WebRtcVideoEngineTest,PropagatesInputFrameTimestamp)589 TEST_F(WebRtcVideoEngineTest, PropagatesInputFrameTimestamp) {
590 AddSupportedVideoCodecType("VP8");
591 FakeCall* fake_call = new FakeCall();
592 call_.reset(fake_call);
593 std::unique_ptr<VideoMediaChannel> channel(
594 SetSendParamsWithAllSupportedCodecs());
595
596 EXPECT_TRUE(
597 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
598
599 webrtc::test::FrameForwarder frame_forwarder;
600 cricket::FakeFrameSource frame_source(1280, 720,
601 rtc::kNumMicrosecsPerSec / 60);
602 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
603 channel->SetSend(true);
604
605 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
606
607 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
608 int64_t last_timestamp = stream->GetLastTimestamp();
609 for (int i = 0; i < 10; i++) {
610 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
611 int64_t timestamp = stream->GetLastTimestamp();
612 int64_t interval = timestamp - last_timestamp;
613
614 // Precision changes from nanosecond to millisecond.
615 // Allow error to be no more than 1.
616 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1);
617
618 last_timestamp = timestamp;
619 }
620
621 frame_forwarder.IncomingCapturedFrame(
622 frame_source.GetFrame(1280, 720, webrtc::VideoRotation::kVideoRotation_0,
623 rtc::kNumMicrosecsPerSec / 30));
624 last_timestamp = stream->GetLastTimestamp();
625 for (int i = 0; i < 10; i++) {
626 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame(
627 1280, 720, webrtc::VideoRotation::kVideoRotation_0,
628 rtc::kNumMicrosecsPerSec / 30));
629 int64_t timestamp = stream->GetLastTimestamp();
630 int64_t interval = timestamp - last_timestamp;
631
632 // Precision changes from nanosecond to millisecond.
633 // Allow error to be no more than 1.
634 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1);
635
636 last_timestamp = timestamp;
637 }
638
639 // Remove stream previously added to free the external encoder instance.
640 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
641 }
642
AssignDefaultAptRtxTypes()643 void WebRtcVideoEngineTest::AssignDefaultAptRtxTypes() {
644 std::vector<VideoCodec> engine_codecs = engine_.send_codecs();
645 RTC_DCHECK(!engine_codecs.empty());
646 for (const cricket::VideoCodec& codec : engine_codecs) {
647 if (codec.name == "rtx") {
648 int associated_payload_type;
649 if (codec.GetParam(kCodecParamAssociatedPayloadType,
650 &associated_payload_type)) {
651 default_apt_rtx_types_[associated_payload_type] = codec.id;
652 }
653 }
654 }
655 }
656
AssignDefaultCodec()657 void WebRtcVideoEngineTest::AssignDefaultCodec() {
658 std::vector<VideoCodec> engine_codecs = engine_.send_codecs();
659 RTC_DCHECK(!engine_codecs.empty());
660 bool codec_set = false;
661 for (const cricket::VideoCodec& codec : engine_codecs) {
662 if (!codec_set && codec.name != "rtx" && codec.name != "red" &&
663 codec.name != "ulpfec") {
664 default_codec_ = codec;
665 codec_set = true;
666 }
667 }
668
669 RTC_DCHECK(codec_set);
670 }
671
GetEngineCodecIndex(const std::string & name) const672 size_t WebRtcVideoEngineTest::GetEngineCodecIndex(
673 const std::string& name) const {
674 const std::vector<cricket::VideoCodec> codecs = engine_.send_codecs();
675 for (size_t i = 0; i < codecs.size(); ++i) {
676 const cricket::VideoCodec engine_codec = codecs[i];
677 if (!absl::EqualsIgnoreCase(name, engine_codec.name))
678 continue;
679 // The tests only use H264 Constrained Baseline. Make sure we don't return
680 // an internal H264 codec from the engine with a different H264 profile.
681 if (absl::EqualsIgnoreCase(name.c_str(), kH264CodecName)) {
682 const absl::optional<webrtc::H264::ProfileLevelId> profile_level_id =
683 webrtc::H264::ParseSdpProfileLevelId(engine_codec.params);
684 if (profile_level_id->profile !=
685 webrtc::H264::kProfileConstrainedBaseline) {
686 continue;
687 }
688 }
689 return i;
690 }
691 // This point should never be reached.
692 ADD_FAILURE() << "Unrecognized codec name: " << name;
693 return -1;
694 }
695
GetEngineCodec(const std::string & name) const696 cricket::VideoCodec WebRtcVideoEngineTest::GetEngineCodec(
697 const std::string& name) const {
698 return engine_.send_codecs()[GetEngineCodecIndex(name)];
699 }
700
AddSupportedVideoCodecType(const std::string & name)701 void WebRtcVideoEngineTest::AddSupportedVideoCodecType(
702 const std::string& name) {
703 encoder_factory_->AddSupportedVideoCodecType(name);
704 decoder_factory_->AddSupportedVideoCodecType(name);
705 }
706
707 VideoMediaChannel*
SetSendParamsWithAllSupportedCodecs()708 WebRtcVideoEngineTest::SetSendParamsWithAllSupportedCodecs() {
709 VideoMediaChannel* channel = engine_.CreateMediaChannel(
710 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
711 video_bitrate_allocator_factory_.get());
712 cricket::VideoSendParameters parameters;
713 // We need to look up the codec in the engine to get the correct payload type.
714 for (const webrtc::SdpVideoFormat& format :
715 encoder_factory_->GetSupportedFormats()) {
716 cricket::VideoCodec engine_codec = GetEngineCodec(format.name);
717 if (!absl::c_linear_search(parameters.codecs, engine_codec)) {
718 parameters.codecs.push_back(engine_codec);
719 }
720 }
721
722 EXPECT_TRUE(channel->SetSendParameters(parameters));
723
724 return channel;
725 }
726
SetRecvParamsWithSupportedCodecs(const std::vector<VideoCodec> & codecs)727 VideoMediaChannel* WebRtcVideoEngineTest::SetRecvParamsWithSupportedCodecs(
728 const std::vector<VideoCodec>& codecs) {
729 VideoMediaChannel* channel = engine_.CreateMediaChannel(
730 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
731 video_bitrate_allocator_factory_.get());
732 cricket::VideoRecvParameters parameters;
733 parameters.codecs = codecs;
734 EXPECT_TRUE(channel->SetRecvParameters(parameters));
735
736 return channel;
737 }
738
ExpectRtpCapabilitySupport(const char * uri,bool supported) const739 void WebRtcVideoEngineTest::ExpectRtpCapabilitySupport(const char* uri,
740 bool supported) const {
741 const std::vector<webrtc::RtpExtension> header_extensions =
742 GetDefaultEnabledRtpHeaderExtensions(engine_);
743 if (supported) {
744 EXPECT_THAT(header_extensions, Contains(Field(&RtpExtension::uri, uri)));
745 } else {
746 EXPECT_THAT(header_extensions, Each(Field(&RtpExtension::uri, StrNe(uri))));
747 }
748 }
749
TEST_F(WebRtcVideoEngineTest,UsesSimulcastAdapterForVp8Factories)750 TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) {
751 AddSupportedVideoCodecType("VP8");
752
753 std::unique_ptr<VideoMediaChannel> channel(
754 SetSendParamsWithAllSupportedCodecs());
755
756 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
757
758 EXPECT_TRUE(channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
759 EXPECT_TRUE(channel->SetSend(true));
760
761 webrtc::test::FrameForwarder frame_forwarder;
762 cricket::FakeFrameSource frame_source(1280, 720,
763 rtc::kNumMicrosecsPerSec / 60);
764 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, &frame_forwarder));
765 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
766
767 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
768
769 // Verify that encoders are configured for simulcast through adapter
770 // (increasing resolution and only configured to send one stream each).
771 int prev_width = -1;
772 for (size_t i = 0; i < encoder_factory_->encoders().size(); ++i) {
773 ASSERT_TRUE(encoder_factory_->encoders()[i]->WaitForInitEncode());
774 webrtc::VideoCodec codec_settings =
775 encoder_factory_->encoders()[i]->GetCodecSettings();
776 EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
777 EXPECT_GT(codec_settings.width, prev_width);
778 prev_width = codec_settings.width;
779 }
780
781 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, nullptr));
782
783 channel.reset();
784 ASSERT_EQ(0u, encoder_factory_->encoders().size());
785 }
786
TEST_F(WebRtcVideoEngineTest,ChannelWithH264CanChangeToVp8)787 TEST_F(WebRtcVideoEngineTest, ChannelWithH264CanChangeToVp8) {
788 AddSupportedVideoCodecType("VP8");
789 AddSupportedVideoCodecType("H264");
790
791 // Frame source.
792 webrtc::test::FrameForwarder frame_forwarder;
793 cricket::FakeFrameSource frame_source(1280, 720,
794 rtc::kNumMicrosecsPerSec / 30);
795
796 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
797 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
798 video_bitrate_allocator_factory_.get()));
799 cricket::VideoSendParameters parameters;
800 parameters.codecs.push_back(GetEngineCodec("H264"));
801 EXPECT_TRUE(channel->SetSendParameters(parameters));
802
803 EXPECT_TRUE(
804 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
805 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
806 // Sending one frame will have allocate the encoder.
807 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
808
809 ASSERT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);
810
811 cricket::VideoSendParameters new_parameters;
812 new_parameters.codecs.push_back(GetEngineCodec("VP8"));
813 EXPECT_TRUE(channel->SetSendParameters(new_parameters));
814
815 // Sending one frame will switch encoder.
816 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
817
818 EXPECT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);
819 }
820
TEST_F(WebRtcVideoEngineTest,UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory)821 TEST_F(WebRtcVideoEngineTest,
822 UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
823 AddSupportedVideoCodecType("VP8");
824 AddSupportedVideoCodecType("H264");
825
826 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
827 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
828 video_bitrate_allocator_factory_.get()));
829 cricket::VideoSendParameters parameters;
830 parameters.codecs.push_back(GetEngineCodec("VP8"));
831 EXPECT_TRUE(channel->SetSendParameters(parameters));
832
833 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
834
835 EXPECT_TRUE(channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
836 EXPECT_TRUE(channel->SetSend(true));
837
838 // Send a fake frame, or else the media engine will configure the simulcast
839 // encoder adapter at a low-enough size that it'll only create a single
840 // encoder layer.
841 webrtc::test::FrameForwarder frame_forwarder;
842 cricket::FakeFrameSource frame_source(1280, 720,
843 rtc::kNumMicrosecsPerSec / 30);
844 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, &frame_forwarder));
845 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
846
847 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
848 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
849 EXPECT_EQ(webrtc::kVideoCodecVP8,
850 encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
851
852 channel.reset();
853 // Make sure DestroyVideoEncoder was called on the factory.
854 EXPECT_EQ(0u, encoder_factory_->encoders().size());
855 }
856
TEST_F(WebRtcVideoEngineTest,DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory)857 TEST_F(WebRtcVideoEngineTest,
858 DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
859 AddSupportedVideoCodecType("VP8");
860 AddSupportedVideoCodecType("H264");
861
862 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
863 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
864 video_bitrate_allocator_factory_.get()));
865 cricket::VideoSendParameters parameters;
866 parameters.codecs.push_back(GetEngineCodec("H264"));
867 EXPECT_TRUE(channel->SetSendParameters(parameters));
868
869 EXPECT_TRUE(
870 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
871
872 // Send a frame of 720p. This should trigger a "real" encoder initialization.
873 webrtc::test::FrameForwarder frame_forwarder;
874 cricket::FakeFrameSource frame_source(1280, 720,
875 rtc::kNumMicrosecsPerSec / 30);
876 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
877 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
878 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
879 ASSERT_EQ(1u, encoder_factory_->encoders().size());
880 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
881 EXPECT_EQ(webrtc::kVideoCodecH264,
882 encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
883
884 channel.reset();
885 // Make sure DestroyVideoEncoder was called on the factory.
886 ASSERT_EQ(0u, encoder_factory_->encoders().size());
887 }
888
TEST_F(WebRtcVideoEngineTest,SimulcastEnabledForH264BehindFieldTrial)889 TEST_F(WebRtcVideoEngineTest, SimulcastEnabledForH264BehindFieldTrial) {
890 RTC_DCHECK(!override_field_trials_);
891 override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>(
892 "WebRTC-H264Simulcast/Enabled/");
893 AddSupportedVideoCodecType("H264");
894
895 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
896 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
897 video_bitrate_allocator_factory_.get()));
898 cricket::VideoSendParameters parameters;
899 parameters.codecs.push_back(GetEngineCodec("H264"));
900 EXPECT_TRUE(channel->SetSendParameters(parameters));
901
902 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
903 EXPECT_TRUE(
904 channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs)));
905
906 // Send a frame of 720p. This should trigger a "real" encoder initialization.
907 webrtc::test::FrameForwarder frame_forwarder;
908 cricket::FakeFrameSource frame_source(1280, 720,
909 rtc::kNumMicrosecsPerSec / 30);
910 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
911 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
912
913 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
914 ASSERT_EQ(1u, encoder_factory_->encoders().size());
915 FakeWebRtcVideoEncoder* encoder = encoder_factory_->encoders()[0];
916 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
917 EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
918 EXPECT_LT(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
919 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], nullptr, nullptr));
920 }
921
922 // Test that the FlexFEC field trial properly alters the output of
923 // WebRtcVideoEngine::codecs(), for an existing |engine_| object.
924 //
925 // TODO(brandtr): Remove this test, when the FlexFEC field trial is gone.
TEST_F(WebRtcVideoEngineTest,Flexfec03SupportedAsInternalCodecBehindFieldTrial)926 TEST_F(WebRtcVideoEngineTest,
927 Flexfec03SupportedAsInternalCodecBehindFieldTrial) {
928 encoder_factory_->AddSupportedVideoCodecType("VP8");
929
930 auto flexfec = Field("name", &VideoCodec::name, "flexfec-03");
931
932 // FlexFEC is not active without field trial.
933 EXPECT_THAT(engine_.send_codecs(), Not(Contains(flexfec)));
934
935 // FlexFEC is active with field trial.
936 RTC_DCHECK(!override_field_trials_);
937 override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>(
938 "WebRTC-FlexFEC-03-Advertised/Enabled/");
939 EXPECT_THAT(engine_.send_codecs(), Contains(flexfec));
940 }
941
942 // Test that codecs are added in the order they are reported from the factory.
TEST_F(WebRtcVideoEngineTest,ReportSupportedCodecs)943 TEST_F(WebRtcVideoEngineTest, ReportSupportedCodecs) {
944 encoder_factory_->AddSupportedVideoCodecType("VP8");
945 const char* kFakeCodecName = "FakeCodec";
946 encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName);
947
948 // The last reported codec should appear after the first codec in the vector.
949 const size_t vp8_index = GetEngineCodecIndex("VP8");
950 const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName);
951 EXPECT_LT(vp8_index, fake_codec_index);
952 }
953
954 // Test that a codec that was added after the engine was initialized
955 // does show up in the codec list after it was added.
TEST_F(WebRtcVideoEngineTest,ReportSupportedAddedCodec)956 TEST_F(WebRtcVideoEngineTest, ReportSupportedAddedCodec) {
957 const char* kFakeExternalCodecName1 = "FakeExternalCodec1";
958 const char* kFakeExternalCodecName2 = "FakeExternalCodec2";
959
960 // Set up external encoder factory with first codec, and initialize engine.
961 encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName1);
962
963 std::vector<cricket::VideoCodec> codecs_before(engine_.send_codecs());
964
965 // Add second codec.
966 encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName2);
967 std::vector<cricket::VideoCodec> codecs_after(engine_.send_codecs());
968 // The codec itself and RTX should have been added.
969 EXPECT_EQ(codecs_before.size() + 2, codecs_after.size());
970
971 // Check that both fake codecs are present and that the second fake codec
972 // appears after the first fake codec.
973 const size_t fake_codec_index1 = GetEngineCodecIndex(kFakeExternalCodecName1);
974 const size_t fake_codec_index2 = GetEngineCodecIndex(kFakeExternalCodecName2);
975 EXPECT_LT(fake_codec_index1, fake_codec_index2);
976 }
977
TEST_F(WebRtcVideoEngineTest,ReportRtxForExternalCodec)978 TEST_F(WebRtcVideoEngineTest, ReportRtxForExternalCodec) {
979 const char* kFakeCodecName = "FakeCodec";
980 encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName);
981
982 const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName);
983 EXPECT_EQ("rtx", engine_.send_codecs().at(fake_codec_index + 1).name);
984 }
985
TEST_F(WebRtcVideoEngineTest,RegisterDecodersIfSupported)986 TEST_F(WebRtcVideoEngineTest, RegisterDecodersIfSupported) {
987 AddSupportedVideoCodecType("VP8");
988 cricket::VideoRecvParameters parameters;
989 parameters.codecs.push_back(GetEngineCodec("VP8"));
990
991 std::unique_ptr<VideoMediaChannel> channel(
992 SetRecvParamsWithSupportedCodecs(parameters.codecs));
993
994 EXPECT_TRUE(
995 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
996 ASSERT_EQ(1u, decoder_factory_->decoders().size());
997
998 // Setting codecs of the same type should not reallocate the decoder.
999 EXPECT_TRUE(channel->SetRecvParameters(parameters));
1000 EXPECT_EQ(1, decoder_factory_->GetNumCreatedDecoders());
1001
1002 // Remove stream previously added to free the external decoder instance.
1003 EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
1004 EXPECT_EQ(0u, decoder_factory_->decoders().size());
1005 }
1006
1007 // Verifies that we can set up decoders.
TEST_F(WebRtcVideoEngineTest,RegisterH264DecoderIfSupported)1008 TEST_F(WebRtcVideoEngineTest, RegisterH264DecoderIfSupported) {
1009 // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We
1010 // can't even query the WebRtcVideoDecoderFactory for supported codecs.
1011 // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
1012 // codecs.
1013 AddSupportedVideoCodecType("H264");
1014 std::vector<cricket::VideoCodec> codecs;
1015 codecs.push_back(GetEngineCodec("H264"));
1016
1017 std::unique_ptr<VideoMediaChannel> channel(
1018 SetRecvParamsWithSupportedCodecs(codecs));
1019
1020 EXPECT_TRUE(
1021 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1022 ASSERT_EQ(1u, decoder_factory_->decoders().size());
1023 }
1024
1025 // Tests when GetSources is called with non-existing ssrc, it will return an
1026 // empty list of RtpSource without crashing.
TEST_F(WebRtcVideoEngineTest,GetSourcesWithNonExistingSsrc)1027 TEST_F(WebRtcVideoEngineTest, GetSourcesWithNonExistingSsrc) {
1028 // Setup an recv stream with |kSsrc|.
1029 AddSupportedVideoCodecType("VP8");
1030 cricket::VideoRecvParameters parameters;
1031 parameters.codecs.push_back(GetEngineCodec("VP8"));
1032 std::unique_ptr<VideoMediaChannel> channel(
1033 SetRecvParamsWithSupportedCodecs(parameters.codecs));
1034
1035 EXPECT_TRUE(
1036 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1037
1038 // Call GetSources with |kSsrc + 1| which doesn't exist.
1039 std::vector<webrtc::RtpSource> sources = channel->GetSources(kSsrc + 1);
1040 EXPECT_EQ(0u, sources.size());
1041 }
1042
TEST(WebRtcVideoEngineNewVideoCodecFactoryTest,NullFactories)1043 TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullFactories) {
1044 std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory;
1045 std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory;
1046 WebRtcVideoEngine engine(std::move(encoder_factory),
1047 std::move(decoder_factory));
1048 EXPECT_EQ(0u, engine.send_codecs().size());
1049 EXPECT_EQ(0u, engine.recv_codecs().size());
1050 }
1051
TEST(WebRtcVideoEngineNewVideoCodecFactoryTest,EmptyFactories)1052 TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, EmptyFactories) {
1053 // |engine| take ownership of the factories.
1054 webrtc::MockVideoEncoderFactory* encoder_factory =
1055 new webrtc::MockVideoEncoderFactory();
1056 webrtc::MockVideoDecoderFactory* decoder_factory =
1057 new webrtc::MockVideoDecoderFactory();
1058 WebRtcVideoEngine engine(
1059 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
1060 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)));
1061 // TODO(kron): Change to Times(1) once send and receive codecs are changed
1062 // to be treated independently.
1063 EXPECT_CALL(*encoder_factory, GetSupportedFormats()).Times(1);
1064 EXPECT_EQ(0u, engine.send_codecs().size());
1065 EXPECT_EQ(0u, engine.recv_codecs().size());
1066 EXPECT_CALL(*encoder_factory, Die());
1067 EXPECT_CALL(*decoder_factory, Die());
1068 }
1069
1070 // Test full behavior in the video engine when video codec factories of the new
1071 // type are injected supporting the single codec Vp8. Check the returned codecs
1072 // from the engine and that we will create a Vp8 encoder and decoder using the
1073 // new factories.
TEST(WebRtcVideoEngineNewVideoCodecFactoryTest,Vp8)1074 TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) {
1075 // |engine| take ownership of the factories.
1076 webrtc::MockVideoEncoderFactory* encoder_factory =
1077 new webrtc::MockVideoEncoderFactory();
1078 webrtc::MockVideoDecoderFactory* decoder_factory =
1079 new webrtc::MockVideoDecoderFactory();
1080 std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
1081 rate_allocator_factory =
1082 std::make_unique<webrtc::MockVideoBitrateAllocatorFactory>();
1083 EXPECT_CALL(*rate_allocator_factory,
1084 CreateVideoBitrateAllocator(Field(&webrtc::VideoCodec::codecType,
1085 webrtc::kVideoCodecVP8)))
1086 .WillOnce(
1087 [] { return std::make_unique<webrtc::MockVideoBitrateAllocator>(); });
1088 WebRtcVideoEngine engine(
1089 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
1090 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)));
1091 const webrtc::SdpVideoFormat vp8_format("VP8");
1092 const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
1093 EXPECT_CALL(*encoder_factory, GetSupportedFormats())
1094 .WillRepeatedly(Return(supported_formats));
1095 EXPECT_CALL(*decoder_factory, GetSupportedFormats())
1096 .WillRepeatedly(Return(supported_formats));
1097
1098 // Verify the codecs from the engine.
1099 const std::vector<VideoCodec> engine_codecs = engine.send_codecs();
1100 // Verify default codecs has been added correctly.
1101 EXPECT_EQ(5u, engine_codecs.size());
1102 EXPECT_EQ("VP8", engine_codecs.at(0).name);
1103
1104 // RTX codec for VP8.
1105 EXPECT_EQ("rtx", engine_codecs.at(1).name);
1106 int vp8_associated_payload;
1107 EXPECT_TRUE(engine_codecs.at(1).GetParam(kCodecParamAssociatedPayloadType,
1108 &vp8_associated_payload));
1109 EXPECT_EQ(vp8_associated_payload, engine_codecs.at(0).id);
1110
1111 EXPECT_EQ(kRedCodecName, engine_codecs.at(2).name);
1112
1113 // RTX codec for RED.
1114 EXPECT_EQ("rtx", engine_codecs.at(3).name);
1115 int red_associated_payload;
1116 EXPECT_TRUE(engine_codecs.at(3).GetParam(kCodecParamAssociatedPayloadType,
1117 &red_associated_payload));
1118 EXPECT_EQ(red_associated_payload, engine_codecs.at(2).id);
1119
1120 EXPECT_EQ(kUlpfecCodecName, engine_codecs.at(4).name);
1121
1122 int associated_payload_type;
1123 EXPECT_TRUE(engine_codecs.at(1).GetParam(
1124 cricket::kCodecParamAssociatedPayloadType, &associated_payload_type));
1125 EXPECT_EQ(engine_codecs.at(0).id, associated_payload_type);
1126 // Verify default parameters has been added to the VP8 codec.
1127 VerifyCodecHasDefaultFeedbackParams(engine_codecs.at(0),
1128 /*lntf_expected=*/false);
1129
1130 // Mock encoder creation. |engine| take ownership of the encoder.
1131 webrtc::VideoEncoderFactory::CodecInfo codec_info;
1132 codec_info.has_internal_source = false;
1133 const webrtc::SdpVideoFormat format("VP8");
1134 EXPECT_CALL(*encoder_factory, QueryVideoEncoder(format))
1135 .WillRepeatedly(Return(codec_info));
1136 rtc::Event encoder_created;
1137 EXPECT_CALL(*encoder_factory, CreateVideoEncoder(format)).WillOnce([&] {
1138 encoder_created.Set();
1139 return std::make_unique<FakeWebRtcVideoEncoder>(nullptr);
1140 });
1141
1142 // Mock decoder creation. |engine| take ownership of the decoder.
1143 EXPECT_CALL(*decoder_factory, CreateVideoDecoder(format)).WillOnce([] {
1144 return std::make_unique<FakeWebRtcVideoDecoder>(nullptr);
1145 });
1146
1147 // Create a call.
1148 webrtc::RtcEventLogNull event_log;
1149 auto task_queue_factory = webrtc::CreateDefaultTaskQueueFactory();
1150 webrtc::Call::Config call_config(&event_log);
1151 webrtc::FieldTrialBasedConfig field_trials;
1152 call_config.trials = &field_trials;
1153 call_config.task_queue_factory = task_queue_factory.get();
1154 const auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
1155
1156 // Create send channel.
1157 const int send_ssrc = 123;
1158 std::unique_ptr<VideoMediaChannel> send_channel(engine.CreateMediaChannel(
1159 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
1160 rate_allocator_factory.get()));
1161 cricket::VideoSendParameters send_parameters;
1162 send_parameters.codecs.push_back(engine_codecs.at(0));
1163 EXPECT_TRUE(send_channel->SetSendParameters(send_parameters));
1164 send_channel->OnReadyToSend(true);
1165 EXPECT_TRUE(
1166 send_channel->AddSendStream(StreamParams::CreateLegacy(send_ssrc)));
1167 EXPECT_TRUE(send_channel->SetSend(true));
1168
1169 // Set capturer.
1170 webrtc::test::FrameForwarder frame_forwarder;
1171 cricket::FakeFrameSource frame_source(1280, 720,
1172 rtc::kNumMicrosecsPerSec / 30);
1173 EXPECT_TRUE(send_channel->SetVideoSend(send_ssrc, nullptr, &frame_forwarder));
1174 // Sending one frame will allocate the encoder.
1175 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
1176 encoder_created.Wait(kTimeout);
1177
1178 // Create recv channel.
1179 const int recv_ssrc = 321;
1180 std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
1181 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
1182 rate_allocator_factory.get()));
1183 cricket::VideoRecvParameters recv_parameters;
1184 recv_parameters.codecs.push_back(engine_codecs.at(0));
1185 EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
1186 EXPECT_TRUE(recv_channel->AddRecvStream(
1187 cricket::StreamParams::CreateLegacy(recv_ssrc)));
1188
1189 // Remove streams previously added to free the encoder and decoder instance.
1190 EXPECT_CALL(*encoder_factory, Die());
1191 EXPECT_CALL(*decoder_factory, Die());
1192 EXPECT_CALL(*rate_allocator_factory, Die());
1193 EXPECT_TRUE(send_channel->RemoveSendStream(send_ssrc));
1194 EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
1195 }
1196
1197 // Test behavior when decoder factory fails to create a decoder (returns null).
TEST(WebRtcVideoEngineNewVideoCodecFactoryTest,NullDecoder)1198 TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullDecoder) {
1199 // |engine| take ownership of the factories.
1200 webrtc::MockVideoEncoderFactory* encoder_factory =
1201 new webrtc::MockVideoEncoderFactory();
1202 webrtc::MockVideoDecoderFactory* decoder_factory =
1203 new webrtc::MockVideoDecoderFactory();
1204 std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
1205 rate_allocator_factory =
1206 std::make_unique<webrtc::MockVideoBitrateAllocatorFactory>();
1207 WebRtcVideoEngine engine(
1208 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
1209 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)));
1210 const webrtc::SdpVideoFormat vp8_format("VP8");
1211 const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
1212 EXPECT_CALL(*encoder_factory, GetSupportedFormats())
1213 .WillRepeatedly(Return(supported_formats));
1214
1215 // Decoder creation fails.
1216 EXPECT_CALL(*decoder_factory, CreateVideoDecoder).WillOnce([] {
1217 return nullptr;
1218 });
1219
1220 // Create a call.
1221 webrtc::RtcEventLogNull event_log;
1222 auto task_queue_factory = webrtc::CreateDefaultTaskQueueFactory();
1223 webrtc::Call::Config call_config(&event_log);
1224 webrtc::FieldTrialBasedConfig field_trials;
1225 call_config.trials = &field_trials;
1226 call_config.task_queue_factory = task_queue_factory.get();
1227 const auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
1228
1229 // Create recv channel.
1230 EXPECT_CALL(*decoder_factory, GetSupportedFormats())
1231 .WillRepeatedly(::testing::Return(supported_formats));
1232 const int recv_ssrc = 321;
1233 std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
1234 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
1235 rate_allocator_factory.get()));
1236 cricket::VideoRecvParameters recv_parameters;
1237 recv_parameters.codecs.push_back(engine.recv_codecs().front());
1238 EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
1239 EXPECT_TRUE(recv_channel->AddRecvStream(
1240 cricket::StreamParams::CreateLegacy(recv_ssrc)));
1241
1242 // Remove streams previously added to free the encoder and decoder instance.
1243 EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
1244 }
1245
TEST_F(WebRtcVideoEngineTest,DISABLED_RecreatesEncoderOnContentTypeChange)1246 TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) {
1247 encoder_factory_->AddSupportedVideoCodecType("VP8");
1248 std::unique_ptr<FakeCall> fake_call(new FakeCall());
1249 std::unique_ptr<VideoMediaChannel> channel(
1250 SetSendParamsWithAllSupportedCodecs());
1251 ASSERT_TRUE(
1252 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1253 cricket::VideoCodec codec = GetEngineCodec("VP8");
1254 cricket::VideoSendParameters parameters;
1255 parameters.codecs.push_back(codec);
1256 channel->OnReadyToSend(true);
1257 channel->SetSend(true);
1258 ASSERT_TRUE(channel->SetSendParameters(parameters));
1259
1260 webrtc::test::FrameForwarder frame_forwarder;
1261 cricket::FakeFrameSource frame_source(1280, 720,
1262 rtc::kNumMicrosecsPerSec / 30);
1263 VideoOptions options;
1264 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1265
1266 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
1267 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
1268 EXPECT_EQ(webrtc::VideoCodecMode::kRealtimeVideo,
1269 encoder_factory_->encoders().back()->GetCodecSettings().mode);
1270
1271 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1272 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
1273 // No change in content type, keep current encoder.
1274 EXPECT_EQ(1, encoder_factory_->GetNumCreatedEncoders());
1275
1276 options.is_screencast.emplace(true);
1277 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1278 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
1279 // Change to screen content, recreate encoder. For the simulcast encoder
1280 // adapter case, this will result in two calls since InitEncode triggers a
1281 // a new instance.
1282 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
1283 EXPECT_EQ(webrtc::VideoCodecMode::kScreensharing,
1284 encoder_factory_->encoders().back()->GetCodecSettings().mode);
1285
1286 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1287 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
1288 // Still screen content, no need to update encoder.
1289 EXPECT_EQ(2, encoder_factory_->GetNumCreatedEncoders());
1290
1291 options.is_screencast.emplace(false);
1292 options.video_noise_reduction.emplace(false);
1293 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1294 // Change back to regular video content, update encoder. Also change
1295 // a non |is_screencast| option just to verify it doesn't affect recreation.
1296 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
1297 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(3));
1298 EXPECT_EQ(webrtc::VideoCodecMode::kRealtimeVideo,
1299 encoder_factory_->encoders().back()->GetCodecSettings().mode);
1300
1301 // Remove stream previously added to free the external encoder instance.
1302 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
1303 EXPECT_EQ(0u, encoder_factory_->encoders().size());
1304 }
1305
1306 class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test {
1307 protected:
GetCallConfig(webrtc::RtcEventLogNull * event_log,webrtc::TaskQueueFactory * task_queue_factory)1308 webrtc::Call::Config GetCallConfig(
1309 webrtc::RtcEventLogNull* event_log,
1310 webrtc::TaskQueueFactory* task_queue_factory) {
1311 webrtc::Call::Config call_config(event_log);
1312 call_config.task_queue_factory = task_queue_factory;
1313 call_config.trials = &field_trials_;
1314 return call_config;
1315 }
1316
WebRtcVideoChannelEncodedFrameCallbackTest()1317 WebRtcVideoChannelEncodedFrameCallbackTest()
1318 : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
1319 call_(absl::WrapUnique(webrtc::Call::Create(
1320 GetCallConfig(&event_log_, task_queue_factory_.get())))),
1321 video_bitrate_allocator_factory_(
1322 webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
1323 engine_(
1324 webrtc::CreateBuiltinVideoEncoderFactory(),
1325 std::make_unique<webrtc::test::FunctionVideoDecoderFactory>(
1326 []() { return std::make_unique<webrtc::test::FakeDecoder>(); },
1327 kSdpVideoFormats)),
1328 channel_(absl::WrapUnique(static_cast<cricket::WebRtcVideoChannel*>(
1329 engine_.CreateMediaChannel(
1330 call_.get(),
1331 cricket::MediaConfig(),
1332 cricket::VideoOptions(),
1333 webrtc::CryptoOptions(),
1334 video_bitrate_allocator_factory_.get())))) {
1335 network_interface_.SetDestination(channel_.get());
1336 channel_->SetInterface(&network_interface_);
1337 cricket::VideoRecvParameters parameters;
1338 parameters.codecs = engine_.recv_codecs();
1339 channel_->SetRecvParameters(parameters);
1340 }
1341
DeliverKeyFrame(uint32_t ssrc)1342 void DeliverKeyFrame(uint32_t ssrc) {
1343 webrtc::RtpPacket packet;
1344 packet.SetMarker(true);
1345 packet.SetPayloadType(96); // VP8
1346 packet.SetSsrc(ssrc);
1347
1348 // VP8 Keyframe + 1 byte payload
1349 uint8_t* buf_ptr = packet.AllocatePayload(11);
1350 memset(buf_ptr, 0, 11); // Pass MSAN (don't care about bytes 1-9)
1351 buf_ptr[0] = 0x10; // Partition ID 0 + beginning of partition.
1352 call_->Receiver()->DeliverPacket(webrtc::MediaType::VIDEO, packet.Buffer(),
1353 /*packet_time_us=*/0);
1354 }
1355
DeliverKeyFrameAndWait(uint32_t ssrc)1356 void DeliverKeyFrameAndWait(uint32_t ssrc) {
1357 DeliverKeyFrame(ssrc);
1358 EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
1359 EXPECT_EQ(0, renderer_.errors());
1360 }
1361
1362 static const std::vector<webrtc::SdpVideoFormat> kSdpVideoFormats;
1363 webrtc::FieldTrialBasedConfig field_trials_;
1364 webrtc::RtcEventLogNull event_log_;
1365 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
1366 std::unique_ptr<webrtc::Call> call_;
1367 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
1368 video_bitrate_allocator_factory_;
1369 WebRtcVideoEngine engine_;
1370 std::unique_ptr<WebRtcVideoChannel> channel_;
1371 cricket::FakeNetworkInterface network_interface_;
1372 cricket::FakeVideoRenderer renderer_;
1373 };
1374
1375 const std::vector<webrtc::SdpVideoFormat>
1376 WebRtcVideoChannelEncodedFrameCallbackTest::kSdpVideoFormats = {
1377 webrtc::SdpVideoFormat("VP8")};
1378
TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,SetEncodedFrameBufferFunction_DefaultStream)1379 TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
1380 SetEncodedFrameBufferFunction_DefaultStream) {
1381 testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)> callback;
1382 EXPECT_CALL(callback, Call);
1383 EXPECT_TRUE(channel_->AddRecvStream(
1384 cricket::StreamParams::CreateLegacy(kSsrc), /*is_default_stream=*/true));
1385 channel_->SetRecordableEncodedFrameCallback(/*ssrc=*/0,
1386 callback.AsStdFunction());
1387 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1388 DeliverKeyFrame(kSsrc);
1389 EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
1390 EXPECT_EQ(0, renderer_.errors());
1391 channel_->RemoveRecvStream(kSsrc);
1392 }
1393
TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,SetEncodedFrameBufferFunction_MatchSsrcWithDefaultStream)1394 TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
1395 SetEncodedFrameBufferFunction_MatchSsrcWithDefaultStream) {
1396 testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)> callback;
1397 EXPECT_CALL(callback, Call);
1398 EXPECT_TRUE(channel_->AddRecvStream(
1399 cricket::StreamParams::CreateLegacy(kSsrc), /*is_default_stream=*/true));
1400 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1401 channel_->SetRecordableEncodedFrameCallback(kSsrc, callback.AsStdFunction());
1402 DeliverKeyFrame(kSsrc);
1403 EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
1404 EXPECT_EQ(0, renderer_.errors());
1405 channel_->RemoveRecvStream(kSsrc);
1406 }
1407
TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,SetEncodedFrameBufferFunction_MatchSsrc)1408 TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
1409 SetEncodedFrameBufferFunction_MatchSsrc) {
1410 testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)> callback;
1411 EXPECT_CALL(callback, Call);
1412 EXPECT_TRUE(channel_->AddRecvStream(
1413 cricket::StreamParams::CreateLegacy(kSsrc), /*is_default_stream=*/false));
1414 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1415 channel_->SetRecordableEncodedFrameCallback(kSsrc, callback.AsStdFunction());
1416 DeliverKeyFrame(kSsrc);
1417 EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
1418 EXPECT_EQ(0, renderer_.errors());
1419 channel_->RemoveRecvStream(kSsrc);
1420 }
1421
TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,SetEncodedFrameBufferFunction_MismatchSsrc)1422 TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
1423 SetEncodedFrameBufferFunction_MismatchSsrc) {
1424 testing::StrictMock<
1425 testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)>>
1426 callback;
1427 EXPECT_TRUE(
1428 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc + 1),
1429 /*is_default_stream=*/false));
1430 EXPECT_TRUE(channel_->SetSink(kSsrc + 1, &renderer_));
1431 channel_->SetRecordableEncodedFrameCallback(kSsrc, callback.AsStdFunction());
1432 DeliverKeyFrame(kSsrc); // Expected to not cause function to fire.
1433 DeliverKeyFrameAndWait(kSsrc + 1);
1434 channel_->RemoveRecvStream(kSsrc + 1);
1435 }
1436
TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,SetEncodedFrameBufferFunction_MismatchSsrcWithDefaultStream)1437 TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
1438 SetEncodedFrameBufferFunction_MismatchSsrcWithDefaultStream) {
1439 testing::StrictMock<
1440 testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)>>
1441 callback;
1442 EXPECT_TRUE(
1443 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc + 1),
1444 /*is_default_stream=*/true));
1445 EXPECT_TRUE(channel_->SetSink(kSsrc + 1, &renderer_));
1446 channel_->SetRecordableEncodedFrameCallback(kSsrc, callback.AsStdFunction());
1447 DeliverKeyFrame(kSsrc); // Expected to not cause function to fire.
1448 DeliverKeyFrameAndWait(kSsrc + 1);
1449 channel_->RemoveRecvStream(kSsrc + 1);
1450 }
1451
1452 class WebRtcVideoChannelBaseTest : public ::testing::Test {
1453 protected:
WebRtcVideoChannelBaseTest()1454 WebRtcVideoChannelBaseTest()
1455 : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
1456 video_bitrate_allocator_factory_(
1457 webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
1458 engine_(webrtc::CreateBuiltinVideoEncoderFactory(),
1459 webrtc::CreateBuiltinVideoDecoderFactory()) {}
1460
SetUp()1461 virtual void SetUp() {
1462 // One testcase calls SetUp in a loop, only create call_ once.
1463 if (!call_) {
1464 webrtc::Call::Config call_config(&event_log_);
1465 call_config.task_queue_factory = task_queue_factory_.get();
1466 call_config.trials = &field_trials_;
1467 call_.reset(webrtc::Call::Create(call_config));
1468 }
1469 cricket::MediaConfig media_config;
1470 // Disabling cpu overuse detection actually disables quality scaling too; it
1471 // implies DegradationPreference kMaintainResolution. Automatic scaling
1472 // needs to be disabled, otherwise, tests which check the size of received
1473 // frames become flaky.
1474 media_config.video.enable_cpu_adaptation = false;
1475 channel_.reset(
1476 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
1477 call_.get(), media_config, cricket::VideoOptions(),
1478 webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())));
1479 channel_->OnReadyToSend(true);
1480 EXPECT_TRUE(channel_.get() != NULL);
1481 network_interface_.SetDestination(channel_.get());
1482 channel_->SetInterface(&network_interface_);
1483 cricket::VideoRecvParameters parameters;
1484 parameters.codecs = engine_.send_codecs();
1485 channel_->SetRecvParameters(parameters);
1486 EXPECT_TRUE(channel_->AddSendStream(DefaultSendStreamParams()));
1487 frame_forwarder_ = std::make_unique<webrtc::test::FrameForwarder>();
1488 frame_source_ = std::make_unique<cricket::FakeFrameSource>(
1489 640, 480, rtc::kNumMicrosecsPerSec / kFramerate);
1490 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
1491 }
1492
1493 // Utility method to setup an additional stream to send and receive video.
1494 // Used to test send and recv between two streams.
SetUpSecondStream()1495 void SetUpSecondStream() {
1496 SetUpSecondStreamWithNoRecv();
1497 // Setup recv for second stream.
1498 EXPECT_TRUE(channel_->AddRecvStream(
1499 cricket::StreamParams::CreateLegacy(kSsrc + 2)));
1500 // Make the second renderer available for use by a new stream.
1501 EXPECT_TRUE(channel_->SetSink(kSsrc + 2, &renderer2_));
1502 }
1503 // Setup an additional stream just to send video. Defer add recv stream.
1504 // This is required if you want to test unsignalled recv of video rtp packets.
SetUpSecondStreamWithNoRecv()1505 void SetUpSecondStreamWithNoRecv() {
1506 // SetUp() already added kSsrc make sure duplicate SSRCs cant be added.
1507 EXPECT_TRUE(
1508 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1509 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1510 EXPECT_FALSE(
1511 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1512 EXPECT_TRUE(channel_->AddSendStream(
1513 cricket::StreamParams::CreateLegacy(kSsrc + 2)));
1514 // We dont add recv for the second stream.
1515
1516 // Setup the receive and renderer for second stream after send.
1517 frame_forwarder_2_ = std::make_unique<webrtc::test::FrameForwarder>();
1518 EXPECT_TRUE(
1519 channel_->SetVideoSend(kSsrc + 2, nullptr, frame_forwarder_2_.get()));
1520 }
TearDown()1521 virtual void TearDown() { channel_.reset(); }
SetDefaultCodec()1522 bool SetDefaultCodec() { return SetOneCodec(DefaultCodec()); }
1523
SetOneCodec(const cricket::VideoCodec & codec)1524 bool SetOneCodec(const cricket::VideoCodec& codec) {
1525 frame_source_ = std::make_unique<cricket::FakeFrameSource>(
1526 kVideoWidth, kVideoHeight, rtc::kNumMicrosecsPerSec / kFramerate);
1527
1528 bool sending = channel_->sending();
1529 bool success = SetSend(false);
1530 if (success) {
1531 cricket::VideoSendParameters parameters;
1532 parameters.codecs.push_back(codec);
1533 success = channel_->SetSendParameters(parameters);
1534 }
1535 if (success) {
1536 success = SetSend(sending);
1537 }
1538 return success;
1539 }
SetSend(bool send)1540 bool SetSend(bool send) { return channel_->SetSend(send); }
SendFrame()1541 void SendFrame() {
1542 if (frame_forwarder_2_) {
1543 frame_forwarder_2_->IncomingCapturedFrame(frame_source_->GetFrame());
1544 }
1545 frame_forwarder_->IncomingCapturedFrame(frame_source_->GetFrame());
1546 }
WaitAndSendFrame(int wait_ms)1547 bool WaitAndSendFrame(int wait_ms) {
1548 bool ret = rtc::Thread::Current()->ProcessMessages(wait_ms);
1549 SendFrame();
1550 return ret;
1551 }
NumRtpBytes()1552 int NumRtpBytes() { return network_interface_.NumRtpBytes(); }
NumRtpBytes(uint32_t ssrc)1553 int NumRtpBytes(uint32_t ssrc) {
1554 return network_interface_.NumRtpBytes(ssrc);
1555 }
NumRtpPackets()1556 int NumRtpPackets() { return network_interface_.NumRtpPackets(); }
NumRtpPackets(uint32_t ssrc)1557 int NumRtpPackets(uint32_t ssrc) {
1558 return network_interface_.NumRtpPackets(ssrc);
1559 }
NumSentSsrcs()1560 int NumSentSsrcs() { return network_interface_.NumSentSsrcs(); }
GetRtpPacket(int index)1561 const rtc::CopyOnWriteBuffer* GetRtpPacket(int index) {
1562 return network_interface_.GetRtpPacket(index);
1563 }
GetPayloadType(const rtc::CopyOnWriteBuffer * p)1564 static int GetPayloadType(const rtc::CopyOnWriteBuffer* p) {
1565 webrtc::RTPHeader header;
1566 EXPECT_TRUE(ParseRtpPacket(p, &header));
1567 return header.payloadType;
1568 }
1569
ParseRtpPacket(const rtc::CopyOnWriteBuffer * p,webrtc::RTPHeader * header)1570 static bool ParseRtpPacket(const rtc::CopyOnWriteBuffer* p,
1571 webrtc::RTPHeader* header) {
1572 std::unique_ptr<webrtc::RtpHeaderParser> parser(
1573 webrtc::RtpHeaderParser::CreateForTest());
1574 return parser->Parse(p->cdata(), p->size(), header);
1575 }
1576
1577 // Tests that we can send and receive frames.
SendAndReceive(const cricket::VideoCodec & codec)1578 void SendAndReceive(const cricket::VideoCodec& codec) {
1579 EXPECT_TRUE(SetOneCodec(codec));
1580 EXPECT_TRUE(SetSend(true));
1581 channel_->SetDefaultSink(&renderer_);
1582 EXPECT_EQ(0, renderer_.num_rendered_frames());
1583 SendFrame();
1584 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1585 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1586 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
1587 }
1588
SendReceiveManyAndGetStats(const cricket::VideoCodec & codec,int duration_sec,int fps)1589 void SendReceiveManyAndGetStats(const cricket::VideoCodec& codec,
1590 int duration_sec,
1591 int fps) {
1592 EXPECT_TRUE(SetOneCodec(codec));
1593 EXPECT_TRUE(SetSend(true));
1594 channel_->SetDefaultSink(&renderer_);
1595 EXPECT_EQ(0, renderer_.num_rendered_frames());
1596 for (int i = 0; i < duration_sec; ++i) {
1597 for (int frame = 1; frame <= fps; ++frame) {
1598 EXPECT_TRUE(WaitAndSendFrame(1000 / fps));
1599 EXPECT_FRAME_WAIT(frame + i * fps, kVideoWidth, kVideoHeight, kTimeout);
1600 }
1601 }
1602 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1603 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
1604 }
1605
GetSenderStats(size_t i)1606 cricket::VideoSenderInfo GetSenderStats(size_t i) {
1607 cricket::VideoMediaInfo info;
1608 EXPECT_TRUE(channel_->GetStats(&info));
1609 return info.senders[i];
1610 }
1611
GetReceiverStats(size_t i)1612 cricket::VideoReceiverInfo GetReceiverStats(size_t i) {
1613 cricket::VideoMediaInfo info;
1614 EXPECT_TRUE(channel_->GetStats(&info));
1615 return info.receivers[i];
1616 }
1617
1618 // Two streams one channel tests.
1619
1620 // Tests that we can send and receive frames.
TwoStreamsSendAndReceive(const cricket::VideoCodec & codec)1621 void TwoStreamsSendAndReceive(const cricket::VideoCodec& codec) {
1622 SetUpSecondStream();
1623 // Test sending and receiving on first stream.
1624 SendAndReceive(codec);
1625 // Test sending and receiving on second stream.
1626 EXPECT_EQ_WAIT(1, renderer2_.num_rendered_frames(), kTimeout);
1627 EXPECT_GT(NumRtpPackets(), 0);
1628 EXPECT_EQ(1, renderer2_.num_rendered_frames());
1629 }
1630
GetEngineCodec(const std::string & name)1631 cricket::VideoCodec GetEngineCodec(const std::string& name) {
1632 for (const cricket::VideoCodec& engine_codec : engine_.send_codecs()) {
1633 if (absl::EqualsIgnoreCase(name, engine_codec.name))
1634 return engine_codec;
1635 }
1636 // This point should never be reached.
1637 ADD_FAILURE() << "Unrecognized codec name: " << name;
1638 return cricket::VideoCodec();
1639 }
1640
DefaultCodec()1641 cricket::VideoCodec DefaultCodec() { return GetEngineCodec("VP8"); }
1642
DefaultSendStreamParams()1643 cricket::StreamParams DefaultSendStreamParams() {
1644 return cricket::StreamParams::CreateLegacy(kSsrc);
1645 }
1646
1647 webrtc::RtcEventLogNull event_log_;
1648 webrtc::FieldTrialBasedConfig field_trials_;
1649 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
1650 std::unique_ptr<webrtc::Call> call_;
1651 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
1652 video_bitrate_allocator_factory_;
1653 WebRtcVideoEngine engine_;
1654
1655 std::unique_ptr<cricket::FakeFrameSource> frame_source_;
1656 std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_;
1657 std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_2_;
1658
1659 std::unique_ptr<WebRtcVideoChannel> channel_;
1660 cricket::FakeNetworkInterface network_interface_;
1661 cricket::FakeVideoRenderer renderer_;
1662
1663 // Used by test cases where 2 streams are run on the same channel.
1664 cricket::FakeVideoRenderer renderer2_;
1665 };
1666
1667 // Test that SetSend works.
TEST_F(WebRtcVideoChannelBaseTest,SetSend)1668 TEST_F(WebRtcVideoChannelBaseTest, SetSend) {
1669 EXPECT_FALSE(channel_->sending());
1670 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
1671 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1672 EXPECT_FALSE(channel_->sending());
1673 EXPECT_TRUE(SetSend(true));
1674 EXPECT_TRUE(channel_->sending());
1675 SendFrame();
1676 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
1677 EXPECT_TRUE(SetSend(false));
1678 EXPECT_FALSE(channel_->sending());
1679 }
1680
1681 // Test that SetSend fails without codecs being set.
TEST_F(WebRtcVideoChannelBaseTest,SetSendWithoutCodecs)1682 TEST_F(WebRtcVideoChannelBaseTest, SetSendWithoutCodecs) {
1683 EXPECT_FALSE(channel_->sending());
1684 EXPECT_FALSE(SetSend(true));
1685 EXPECT_FALSE(channel_->sending());
1686 }
1687
1688 // Test that we properly set the send and recv buffer sizes by the time
1689 // SetSend is called.
TEST_F(WebRtcVideoChannelBaseTest,SetSendSetsTransportBufferSizes)1690 TEST_F(WebRtcVideoChannelBaseTest, SetSendSetsTransportBufferSizes) {
1691 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1692 EXPECT_TRUE(SetSend(true));
1693 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
1694 EXPECT_EQ(256 * 1024, network_interface_.recvbuf_size());
1695 }
1696
1697 // Test that we properly set the send and recv buffer sizes when overriding
1698 // via field trials.
TEST_F(WebRtcVideoChannelBaseTest,OverridesRecvBufferSize)1699 TEST_F(WebRtcVideoChannelBaseTest, OverridesRecvBufferSize) {
1700 // Set field trial to override the default recv buffer size, and then re-run
1701 // setup where the interface is created and configured.
1702 const int kCustomRecvBufferSize = 123456;
1703 webrtc::test::ScopedFieldTrials field_trial(
1704 "WebRTC-IncreasedReceivebuffers/123456/");
1705 SetUp();
1706
1707 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1708 EXPECT_TRUE(SetSend(true));
1709 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
1710 EXPECT_EQ(kCustomRecvBufferSize, network_interface_.recvbuf_size());
1711 }
1712
1713 // Test that we properly set the send and recv buffer sizes when overriding
1714 // via field trials with suffix.
TEST_F(WebRtcVideoChannelBaseTest,OverridesRecvBufferSizeWithSuffix)1715 TEST_F(WebRtcVideoChannelBaseTest, OverridesRecvBufferSizeWithSuffix) {
1716 // Set field trial to override the default recv buffer size, and then re-run
1717 // setup where the interface is created and configured.
1718 const int kCustomRecvBufferSize = 123456;
1719 webrtc::test::ScopedFieldTrials field_trial(
1720 "WebRTC-IncreasedReceivebuffers/123456_Dogfood/");
1721 SetUp();
1722
1723 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1724 EXPECT_TRUE(SetSend(true));
1725 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
1726 EXPECT_EQ(kCustomRecvBufferSize, network_interface_.recvbuf_size());
1727 }
1728
1729 // Test that we properly set the send and recv buffer sizes when overriding
1730 // via field trials that don't make any sense.
TEST_F(WebRtcVideoChannelBaseTest,InvalidRecvBufferSize)1731 TEST_F(WebRtcVideoChannelBaseTest, InvalidRecvBufferSize) {
1732 // Set bogus field trial values to override the default recv buffer size, and
1733 // then re-run setup where the interface is created and configured. The
1734 // default value should still be used.
1735
1736 for (std::string group : {" ", "NotANumber", "-1", "0"}) {
1737 std::string field_trial_string = "WebRTC-IncreasedReceivebuffers/";
1738 field_trial_string += group;
1739 field_trial_string += "/";
1740 webrtc::test::ScopedFieldTrials field_trial(field_trial_string);
1741 SetUp();
1742
1743 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1744 EXPECT_TRUE(SetSend(true));
1745 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
1746 EXPECT_EQ(256 * 1024, network_interface_.recvbuf_size());
1747 }
1748 }
1749
1750 // Test that stats work properly for a 1-1 call.
TEST_F(WebRtcVideoChannelBaseTest,GetStats)1751 TEST_F(WebRtcVideoChannelBaseTest, GetStats) {
1752 SetUp();
1753
1754 const int kDurationSec = 3;
1755 const int kFps = 10;
1756 SendReceiveManyAndGetStats(DefaultCodec(), kDurationSec, kFps);
1757
1758 cricket::VideoMediaInfo info;
1759 EXPECT_TRUE(channel_->GetStats(&info));
1760
1761 ASSERT_EQ(1U, info.senders.size());
1762 // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
1763 // For webrtc, bytes_sent does not include the RTP header length.
1764 EXPECT_EQ(info.senders[0].payload_bytes_sent,
1765 NumRtpBytes() - kRtpHeaderSize * NumRtpPackets());
1766 EXPECT_EQ(NumRtpPackets(), info.senders[0].packets_sent);
1767 EXPECT_EQ(0.0, info.senders[0].fraction_lost);
1768 ASSERT_TRUE(info.senders[0].codec_payload_type);
1769 EXPECT_EQ(DefaultCodec().id, *info.senders[0].codec_payload_type);
1770 EXPECT_EQ(0, info.senders[0].firs_rcvd);
1771 EXPECT_EQ(0, info.senders[0].plis_rcvd);
1772 EXPECT_EQ(0, info.senders[0].nacks_rcvd);
1773 EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width);
1774 EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height);
1775 EXPECT_GT(info.senders[0].framerate_input, 0);
1776 EXPECT_GT(info.senders[0].framerate_sent, 0);
1777
1778 EXPECT_EQ(1U, info.send_codecs.count(DefaultCodec().id));
1779 EXPECT_EQ(DefaultCodec().ToCodecParameters(),
1780 info.send_codecs[DefaultCodec().id]);
1781
1782 ASSERT_EQ(1U, info.receivers.size());
1783 EXPECT_EQ(1U, info.senders[0].ssrcs().size());
1784 EXPECT_EQ(1U, info.receivers[0].ssrcs().size());
1785 EXPECT_EQ(info.senders[0].ssrcs()[0], info.receivers[0].ssrcs()[0]);
1786 ASSERT_TRUE(info.receivers[0].codec_payload_type);
1787 EXPECT_EQ(DefaultCodec().id, *info.receivers[0].codec_payload_type);
1788 EXPECT_EQ(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(),
1789 info.receivers[0].payload_bytes_rcvd);
1790 EXPECT_EQ(NumRtpPackets(), info.receivers[0].packets_rcvd);
1791 EXPECT_EQ(0, info.receivers[0].packets_lost);
1792 // TODO(asapersson): Not set for webrtc. Handle missing stats.
1793 // EXPECT_EQ(0, info.receivers[0].packets_concealed);
1794 EXPECT_EQ(0, info.receivers[0].firs_sent);
1795 EXPECT_EQ(0, info.receivers[0].plis_sent);
1796 EXPECT_EQ(0, info.receivers[0].nacks_sent);
1797 EXPECT_EQ(kVideoWidth, info.receivers[0].frame_width);
1798 EXPECT_EQ(kVideoHeight, info.receivers[0].frame_height);
1799 EXPECT_GT(info.receivers[0].framerate_rcvd, 0);
1800 EXPECT_GT(info.receivers[0].framerate_decoded, 0);
1801 EXPECT_GT(info.receivers[0].framerate_output, 0);
1802
1803 EXPECT_EQ(1U, info.receive_codecs.count(DefaultCodec().id));
1804 EXPECT_EQ(DefaultCodec().ToCodecParameters(),
1805 info.receive_codecs[DefaultCodec().id]);
1806 }
1807
1808 // Test that stats work properly for a conf call with multiple recv streams.
TEST_F(WebRtcVideoChannelBaseTest,GetStatsMultipleRecvStreams)1809 TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleRecvStreams) {
1810 SetUp();
1811
1812 cricket::FakeVideoRenderer renderer1, renderer2;
1813 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1814 cricket::VideoSendParameters parameters;
1815 parameters.codecs.push_back(DefaultCodec());
1816 parameters.conference_mode = true;
1817 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1818 EXPECT_TRUE(SetSend(true));
1819 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1820 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1821 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
1822 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
1823 EXPECT_EQ(0, renderer1.num_rendered_frames());
1824 EXPECT_EQ(0, renderer2.num_rendered_frames());
1825 std::vector<uint32_t> ssrcs;
1826 ssrcs.push_back(1);
1827 ssrcs.push_back(2);
1828 network_interface_.SetConferenceMode(true, ssrcs);
1829 SendFrame();
1830 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight,
1831 kTimeout);
1832 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight,
1833 kTimeout);
1834
1835 EXPECT_TRUE(channel_->SetSend(false));
1836
1837 cricket::VideoMediaInfo info;
1838 EXPECT_TRUE(channel_->GetStats(&info));
1839 ASSERT_EQ(1U, info.senders.size());
1840 // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
1841 // For webrtc, bytes_sent does not include the RTP header length.
1842 EXPECT_EQ_WAIT(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(),
1843 GetSenderStats(0).payload_bytes_sent, kTimeout);
1844 EXPECT_EQ_WAIT(NumRtpPackets(), GetSenderStats(0).packets_sent, kTimeout);
1845 EXPECT_EQ(kVideoWidth, GetSenderStats(0).send_frame_width);
1846 EXPECT_EQ(kVideoHeight, GetSenderStats(0).send_frame_height);
1847
1848 ASSERT_EQ(2U, info.receivers.size());
1849 for (size_t i = 0; i < info.receivers.size(); ++i) {
1850 EXPECT_EQ(1U, GetReceiverStats(i).ssrcs().size());
1851 EXPECT_EQ(i + 1, GetReceiverStats(i).ssrcs()[0]);
1852 EXPECT_EQ_WAIT(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(),
1853 GetReceiverStats(i).payload_bytes_rcvd, kTimeout);
1854 EXPECT_EQ_WAIT(NumRtpPackets(), GetReceiverStats(i).packets_rcvd, kTimeout);
1855 EXPECT_EQ_WAIT(kVideoWidth, GetReceiverStats(i).frame_width, kTimeout);
1856 EXPECT_EQ_WAIT(kVideoHeight, GetReceiverStats(i).frame_height, kTimeout);
1857 }
1858 }
1859
1860 // Test that stats work properly for a conf call with multiple send streams.
TEST_F(WebRtcVideoChannelBaseTest,GetStatsMultipleSendStreams)1861 TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleSendStreams) {
1862 // Normal setup; note that we set the SSRC explicitly to ensure that
1863 // it will come first in the senders map.
1864 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1865 cricket::VideoSendParameters parameters;
1866 parameters.codecs.push_back(DefaultCodec());
1867 parameters.conference_mode = true;
1868 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1869 EXPECT_TRUE(
1870 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1871 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1872 EXPECT_TRUE(SetSend(true));
1873 SendFrame();
1874 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
1875 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1876
1877 // Add an additional capturer, and hook up a renderer to receive it.
1878 cricket::FakeVideoRenderer renderer2;
1879 webrtc::test::FrameForwarder frame_forwarder;
1880 const int kTestWidth = 160;
1881 const int kTestHeight = 120;
1882 cricket::FakeFrameSource frame_source(kTestWidth, kTestHeight,
1883 rtc::kNumMicrosecsPerSec / 5);
1884 EXPECT_TRUE(
1885 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(5678)));
1886 EXPECT_TRUE(channel_->SetVideoSend(5678, nullptr, &frame_forwarder));
1887 EXPECT_TRUE(
1888 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(5678)));
1889 EXPECT_TRUE(channel_->SetSink(5678, &renderer2));
1890 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
1891 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight,
1892 kTimeout);
1893
1894 // Get stats, and make sure they are correct for two senders. We wait until
1895 // the number of expected packets have been sent to avoid races where we
1896 // check stats before it has been updated.
1897 cricket::VideoMediaInfo info;
1898 for (uint32_t i = 0; i < kTimeout; ++i) {
1899 rtc::Thread::Current()->ProcessMessages(1);
1900 EXPECT_TRUE(channel_->GetStats(&info));
1901 ASSERT_EQ(2U, info.senders.size());
1902 if (info.senders[0].packets_sent + info.senders[1].packets_sent ==
1903 NumRtpPackets()) {
1904 // Stats have been updated for both sent frames, expectations can be
1905 // checked now.
1906 break;
1907 }
1908 }
1909 EXPECT_EQ(NumRtpPackets(),
1910 info.senders[0].packets_sent + info.senders[1].packets_sent)
1911 << "Timed out while waiting for packet counts for all sent packets.";
1912 EXPECT_EQ(1U, info.senders[0].ssrcs().size());
1913 EXPECT_EQ(1234U, info.senders[0].ssrcs()[0]);
1914 EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width);
1915 EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height);
1916 EXPECT_EQ(1U, info.senders[1].ssrcs().size());
1917 EXPECT_EQ(5678U, info.senders[1].ssrcs()[0]);
1918 EXPECT_EQ(kTestWidth, info.senders[1].send_frame_width);
1919 EXPECT_EQ(kTestHeight, info.senders[1].send_frame_height);
1920 // The capturer must be unregistered here as it runs out of it's scope next.
1921 channel_->SetVideoSend(5678, nullptr, nullptr);
1922 }
1923
1924 // Test that we can set the bandwidth.
TEST_F(WebRtcVideoChannelBaseTest,SetSendBandwidth)1925 TEST_F(WebRtcVideoChannelBaseTest, SetSendBandwidth) {
1926 cricket::VideoSendParameters parameters;
1927 parameters.codecs.push_back(DefaultCodec());
1928 parameters.max_bandwidth_bps = -1; // <= 0 means unlimited.
1929 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1930 parameters.max_bandwidth_bps = 128 * 1024;
1931 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1932 }
1933
1934 // Test that we can set the SSRC for the default send source.
TEST_F(WebRtcVideoChannelBaseTest,SetSendSsrc)1935 TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrc) {
1936 EXPECT_TRUE(SetDefaultCodec());
1937 EXPECT_TRUE(SetSend(true));
1938 SendFrame();
1939 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
1940 webrtc::RTPHeader header;
1941 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1942 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1943 EXPECT_EQ(kSsrc, header.ssrc);
1944
1945 // Packets are being paced out, so these can mismatch between the first and
1946 // second call to NumRtpPackets until pending packets are paced out.
1947 EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.ssrc), kTimeout);
1948 EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.ssrc), kTimeout);
1949 EXPECT_EQ(1, NumSentSsrcs());
1950 EXPECT_EQ(0, NumRtpPackets(kSsrc - 1));
1951 EXPECT_EQ(0, NumRtpBytes(kSsrc - 1));
1952 }
1953
1954 // Test that we can set the SSRC even after codecs are set.
TEST_F(WebRtcVideoChannelBaseTest,SetSendSsrcAfterSetCodecs)1955 TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrcAfterSetCodecs) {
1956 // Remove stream added in Setup.
1957 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1958 EXPECT_TRUE(SetDefaultCodec());
1959 EXPECT_TRUE(
1960 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(999)));
1961 EXPECT_TRUE(channel_->SetVideoSend(999u, nullptr, frame_forwarder_.get()));
1962 EXPECT_TRUE(SetSend(true));
1963 EXPECT_TRUE(WaitAndSendFrame(0));
1964 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
1965 webrtc::RTPHeader header;
1966 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1967 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1968 EXPECT_EQ(999u, header.ssrc);
1969 // Packets are being paced out, so these can mismatch between the first and
1970 // second call to NumRtpPackets until pending packets are paced out.
1971 EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.ssrc), kTimeout);
1972 EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.ssrc), kTimeout);
1973 EXPECT_EQ(1, NumSentSsrcs());
1974 EXPECT_EQ(0, NumRtpPackets(kSsrc));
1975 EXPECT_EQ(0, NumRtpBytes(kSsrc));
1976 }
1977
1978 // Test that we can set the default video renderer before and after
1979 // media is received.
TEST_F(WebRtcVideoChannelBaseTest,SetSink)1980 TEST_F(WebRtcVideoChannelBaseTest, SetSink) {
1981 uint8_t data1[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
1982 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1983
1984 rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
1985 rtc::SetBE32(packet1.data() + 8, kSsrc);
1986 channel_->SetDefaultSink(NULL);
1987 EXPECT_TRUE(SetDefaultCodec());
1988 EXPECT_TRUE(SetSend(true));
1989 EXPECT_EQ(0, renderer_.num_rendered_frames());
1990 channel_->OnPacketReceived(packet1, /* packet_time_us */ -1);
1991 channel_->SetDefaultSink(&renderer_);
1992 SendFrame();
1993 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1994 }
1995
1996 // Tests setting up and configuring a send stream.
TEST_F(WebRtcVideoChannelBaseTest,AddRemoveSendStreams)1997 TEST_F(WebRtcVideoChannelBaseTest, AddRemoveSendStreams) {
1998 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1999 EXPECT_TRUE(SetSend(true));
2000 channel_->SetDefaultSink(&renderer_);
2001 SendFrame();
2002 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
2003 EXPECT_GT(NumRtpPackets(), 0);
2004 webrtc::RTPHeader header;
2005 size_t last_packet = NumRtpPackets() - 1;
2006 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(
2007 GetRtpPacket(static_cast<int>(last_packet)));
2008 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
2009 EXPECT_EQ(kSsrc, header.ssrc);
2010
2011 // Remove the send stream that was added during Setup.
2012 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
2013 int rtp_packets = NumRtpPackets();
2014
2015 EXPECT_TRUE(
2016 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(789u)));
2017 EXPECT_TRUE(channel_->SetVideoSend(789u, nullptr, frame_forwarder_.get()));
2018 EXPECT_EQ(rtp_packets, NumRtpPackets());
2019 // Wait 30ms to guarantee the engine does not drop the frame.
2020 EXPECT_TRUE(WaitAndSendFrame(30));
2021 EXPECT_TRUE_WAIT(NumRtpPackets() > rtp_packets, kTimeout);
2022
2023 last_packet = NumRtpPackets() - 1;
2024 p.reset(GetRtpPacket(static_cast<int>(last_packet)));
2025 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
2026 EXPECT_EQ(789u, header.ssrc);
2027 }
2028
2029 // Tests the behavior of incoming streams in a conference scenario.
TEST_F(WebRtcVideoChannelBaseTest,SimulateConference)2030 TEST_F(WebRtcVideoChannelBaseTest, SimulateConference) {
2031 cricket::FakeVideoRenderer renderer1, renderer2;
2032 EXPECT_TRUE(SetDefaultCodec());
2033 cricket::VideoSendParameters parameters;
2034 parameters.codecs.push_back(DefaultCodec());
2035 parameters.conference_mode = true;
2036 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2037 EXPECT_TRUE(SetSend(true));
2038 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2039 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2040 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
2041 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
2042 EXPECT_EQ(0, renderer1.num_rendered_frames());
2043 EXPECT_EQ(0, renderer2.num_rendered_frames());
2044 std::vector<uint32_t> ssrcs;
2045 ssrcs.push_back(1);
2046 ssrcs.push_back(2);
2047 network_interface_.SetConferenceMode(true, ssrcs);
2048 SendFrame();
2049 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight,
2050 kTimeout);
2051 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight,
2052 kTimeout);
2053
2054 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
2055 EXPECT_EQ(DefaultCodec().id, GetPayloadType(p.get()));
2056 EXPECT_EQ(kVideoWidth, renderer1.width());
2057 EXPECT_EQ(kVideoHeight, renderer1.height());
2058 EXPECT_EQ(kVideoWidth, renderer2.width());
2059 EXPECT_EQ(kVideoHeight, renderer2.height());
2060 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2061 EXPECT_TRUE(channel_->RemoveRecvStream(1));
2062 }
2063
2064 // Tests that we can add and remove capturers and frames are sent out properly
TEST_F(WebRtcVideoChannelBaseTest,DISABLED_AddRemoveCapturer)2065 TEST_F(WebRtcVideoChannelBaseTest, DISABLED_AddRemoveCapturer) {
2066 using cricket::FOURCC_I420;
2067 using cricket::VideoCodec;
2068 using cricket::VideoFormat;
2069 using cricket::VideoOptions;
2070
2071 VideoCodec codec = DefaultCodec();
2072 const int time_between_send_ms = VideoFormat::FpsToInterval(kFramerate);
2073 EXPECT_TRUE(SetOneCodec(codec));
2074 EXPECT_TRUE(SetSend(true));
2075 channel_->SetDefaultSink(&renderer_);
2076 EXPECT_EQ(0, renderer_.num_rendered_frames());
2077 SendFrame();
2078 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
2079
2080 webrtc::test::FrameForwarder frame_forwarder;
2081 cricket::FakeFrameSource frame_source(480, 360, rtc::kNumMicrosecsPerSec / 30,
2082 rtc::kNumMicrosecsPerSec / 30);
2083
2084 // TODO(nisse): This testcase fails if we don't configure
2085 // screencast. It's unclear why, I see nothing obvious in this
2086 // test which is related to screencast logic.
2087 VideoOptions video_options;
2088 video_options.is_screencast = true;
2089 channel_->SetVideoSend(kSsrc, &video_options, nullptr);
2090
2091 int captured_frames = 1;
2092 for (int iterations = 0; iterations < 2; ++iterations) {
2093 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
2094 rtc::Thread::Current()->ProcessMessages(time_between_send_ms);
2095 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
2096
2097 ++captured_frames;
2098 // Wait until frame of right size is captured.
2099 EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
2100 480 == renderer_.width() &&
2101 360 == renderer_.height() && !renderer_.black_frame(),
2102 kTimeout);
2103 EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
2104 EXPECT_EQ(480, renderer_.width());
2105 EXPECT_EQ(360, renderer_.height());
2106 captured_frames = renderer_.num_rendered_frames() + 1;
2107 EXPECT_FALSE(renderer_.black_frame());
2108 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
2109 // Make sure a black frame is generated within the specified timeout.
2110 // The black frame should be the resolution of the previous frame to
2111 // prevent expensive encoder reconfigurations.
2112 EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
2113 480 == renderer_.width() &&
2114 360 == renderer_.height() && renderer_.black_frame(),
2115 kTimeout);
2116 EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
2117 EXPECT_EQ(480, renderer_.width());
2118 EXPECT_EQ(360, renderer_.height());
2119 EXPECT_TRUE(renderer_.black_frame());
2120
2121 // The black frame has the same timestamp as the next frame since it's
2122 // timestamp is set to the last frame's timestamp + interval. WebRTC will
2123 // not render a frame with the same timestamp so capture another frame
2124 // with the frame capturer to increment the next frame's timestamp.
2125 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
2126 }
2127 }
2128
2129 // Tests that if SetVideoSend is called with a NULL capturer after the
2130 // capturer was already removed, the application doesn't crash (and no black
2131 // frame is sent).
TEST_F(WebRtcVideoChannelBaseTest,RemoveCapturerWithoutAdd)2132 TEST_F(WebRtcVideoChannelBaseTest, RemoveCapturerWithoutAdd) {
2133 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
2134 EXPECT_TRUE(SetSend(true));
2135 channel_->SetDefaultSink(&renderer_);
2136 EXPECT_EQ(0, renderer_.num_rendered_frames());
2137 SendFrame();
2138 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
2139 // Wait for one frame so they don't get dropped because we send frames too
2140 // tightly.
2141 rtc::Thread::Current()->ProcessMessages(30);
2142 // Remove the capturer.
2143 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
2144
2145 // No capturer was added, so this SetVideoSend shouldn't do anything.
2146 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
2147 rtc::Thread::Current()->ProcessMessages(300);
2148 // Verify no more frames were sent.
2149 EXPECT_EQ(1, renderer_.num_rendered_frames());
2150 }
2151
2152 // Tests that we can add and remove capturer as unique sources.
TEST_F(WebRtcVideoChannelBaseTest,AddRemoveCapturerMultipleSources)2153 TEST_F(WebRtcVideoChannelBaseTest, AddRemoveCapturerMultipleSources) {
2154 // WebRTC implementation will drop frames if pushed to quickly. Wait the
2155 // interval time to avoid that.
2156 // WebRTC implementation will drop frames if pushed to quickly. Wait the
2157 // interval time to avoid that.
2158 // Set up the stream associated with the engine.
2159 EXPECT_TRUE(
2160 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
2161 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
2162 cricket::VideoFormat capture_format(
2163 kVideoWidth, kVideoHeight,
2164 cricket::VideoFormat::FpsToInterval(kFramerate), cricket::FOURCC_I420);
2165 // Set up additional stream 1.
2166 cricket::FakeVideoRenderer renderer1;
2167 EXPECT_FALSE(channel_->SetSink(1, &renderer1));
2168 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2169 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
2170 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
2171
2172 webrtc::test::FrameForwarder frame_forwarder1;
2173 cricket::FakeFrameSource frame_source(kVideoWidth, kVideoHeight,
2174 rtc::kNumMicrosecsPerSec / kFramerate);
2175
2176 // Set up additional stream 2.
2177 cricket::FakeVideoRenderer renderer2;
2178 EXPECT_FALSE(channel_->SetSink(2, &renderer2));
2179 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
2180 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
2181 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
2182 webrtc::test::FrameForwarder frame_forwarder2;
2183
2184 // State for all the streams.
2185 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
2186 // A limitation in the lmi implementation requires that SetVideoSend() is
2187 // called after SetOneCodec().
2188 // TODO(hellner): this seems like an unnecessary constraint, fix it.
2189 EXPECT_TRUE(channel_->SetVideoSend(1, nullptr, &frame_forwarder1));
2190 EXPECT_TRUE(channel_->SetVideoSend(2, nullptr, &frame_forwarder2));
2191 EXPECT_TRUE(SetSend(true));
2192 // Test capturer associated with engine.
2193 const int kTestWidth = 160;
2194 const int kTestHeight = 120;
2195 frame_forwarder1.IncomingCapturedFrame(frame_source.GetFrame(
2196 kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0,
2197 rtc::kNumMicrosecsPerSec / kFramerate));
2198 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kTestWidth, kTestHeight,
2199 kTimeout);
2200 // Capture a frame with additional capturer2, frames should be received
2201 frame_forwarder2.IncomingCapturedFrame(frame_source.GetFrame(
2202 kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0,
2203 rtc::kNumMicrosecsPerSec / kFramerate));
2204 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight,
2205 kTimeout);
2206 // Successfully remove the capturer.
2207 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
2208 // The capturers must be unregistered here as it runs out of it's scope
2209 // next.
2210 EXPECT_TRUE(channel_->SetVideoSend(1, nullptr, nullptr));
2211 EXPECT_TRUE(channel_->SetVideoSend(2, nullptr, nullptr));
2212 }
2213
2214 // Tests empty StreamParams is rejected.
TEST_F(WebRtcVideoChannelBaseTest,RejectEmptyStreamParams)2215 TEST_F(WebRtcVideoChannelBaseTest, RejectEmptyStreamParams) {
2216 // Remove the send stream that was added during Setup.
2217 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
2218
2219 cricket::StreamParams empty;
2220 EXPECT_FALSE(channel_->AddSendStream(empty));
2221 EXPECT_TRUE(
2222 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(789u)));
2223 }
2224
2225 // Test that multiple send streams can be created and deleted properly.
TEST_F(WebRtcVideoChannelBaseTest,MultipleSendStreams)2226 TEST_F(WebRtcVideoChannelBaseTest, MultipleSendStreams) {
2227 // Remove stream added in Setup. I.e. remove stream corresponding to default
2228 // channel.
2229 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
2230 const unsigned int kSsrcsSize = sizeof(kSsrcs4) / sizeof(kSsrcs4[0]);
2231 for (unsigned int i = 0; i < kSsrcsSize; ++i) {
2232 EXPECT_TRUE(channel_->AddSendStream(
2233 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
2234 }
2235 // Delete one of the non default channel streams, let the destructor delete
2236 // the remaining ones.
2237 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
2238 // Stream should already be deleted.
2239 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
2240 }
2241
TEST_F(WebRtcVideoChannelBaseTest,SendAndReceiveVp8Vga)2242 TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Vga) {
2243 SendAndReceive(GetEngineCodec("VP8"));
2244 }
2245
TEST_F(WebRtcVideoChannelBaseTest,SendAndReceiveVp8Qvga)2246 TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Qvga) {
2247 SendAndReceive(GetEngineCodec("VP8"));
2248 }
2249
TEST_F(WebRtcVideoChannelBaseTest,SendAndReceiveVp8SvcQqvga)2250 TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8SvcQqvga) {
2251 SendAndReceive(GetEngineCodec("VP8"));
2252 }
2253
TEST_F(WebRtcVideoChannelBaseTest,TwoStreamsSendAndReceive)2254 TEST_F(WebRtcVideoChannelBaseTest, TwoStreamsSendAndReceive) {
2255 // Set a high bitrate to not be downscaled by VP8 due to low initial start
2256 // bitrates. This currently happens at <250k, and two streams sharing 300k
2257 // initially will use QVGA instead of VGA.
2258 // TODO(pbos): Set up the quality scaler so that both senders reliably start
2259 // at QVGA, then verify that instead.
2260 cricket::VideoCodec codec = GetEngineCodec("VP8");
2261 codec.params[kCodecParamStartBitrate] = "1000000";
2262 TwoStreamsSendAndReceive(codec);
2263 }
2264
2265 #if defined(RTC_ENABLE_VP9)
2266
TEST_F(WebRtcVideoChannelBaseTest,RequestEncoderFallback)2267 TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderFallback) {
2268 cricket::VideoSendParameters parameters;
2269 parameters.codecs.push_back(GetEngineCodec("VP9"));
2270 parameters.codecs.push_back(GetEngineCodec("VP8"));
2271 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2272
2273 VideoCodec codec;
2274 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2275 EXPECT_EQ("VP9", codec.name);
2276
2277 // RequestEncoderFallback will post a task to the worker thread (which is also
2278 // the current thread), hence the ProcessMessages call.
2279 channel_->RequestEncoderFallback();
2280 rtc::Thread::Current()->ProcessMessages(30);
2281 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2282 EXPECT_EQ("VP8", codec.name);
2283
2284 // No other codec to fall back to, keep using VP8.
2285 channel_->RequestEncoderFallback();
2286 rtc::Thread::Current()->ProcessMessages(30);
2287 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2288 EXPECT_EQ("VP8", codec.name);
2289 }
2290
TEST_F(WebRtcVideoChannelBaseTest,RequestEncoderSwitchWithConfig)2291 TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchWithConfig) {
2292 const std::string kParam = "the-param";
2293 const std::string kPing = "ping";
2294 const std::string kPong = "pong";
2295
2296 cricket::VideoSendParameters parameters;
2297 VideoCodec vp9 = GetEngineCodec("VP9");
2298 vp9.params[kParam] = kPong;
2299 parameters.codecs.push_back(vp9);
2300
2301 VideoCodec vp8 = GetEngineCodec("VP8");
2302 vp8.params[kParam] = kPing;
2303 parameters.codecs.push_back(vp8);
2304
2305 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2306 channel_->SetVideoCodecSwitchingEnabled(true);
2307
2308 VideoCodec codec;
2309 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2310 EXPECT_THAT(codec.name, Eq("VP9"));
2311
2312 // RequestEncoderSwitch will post a task to the worker thread (which is also
2313 // the current thread), hence the ProcessMessages call.
2314 webrtc::EncoderSwitchRequestCallback::Config conf1{"VP8", kParam, kPing};
2315 channel_->RequestEncoderSwitch(conf1);
2316 rtc::Thread::Current()->ProcessMessages(30);
2317 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2318 EXPECT_THAT(codec.name, Eq("VP8"));
2319 EXPECT_THAT(codec.params, Contains(Pair(kParam, kPing)));
2320
2321 webrtc::EncoderSwitchRequestCallback::Config conf2{"VP9", kParam, kPong};
2322 channel_->RequestEncoderSwitch(conf2);
2323 rtc::Thread::Current()->ProcessMessages(30);
2324 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2325 EXPECT_THAT(codec.name, Eq("VP9"));
2326 EXPECT_THAT(codec.params, Contains(Pair(kParam, kPong)));
2327 }
2328
TEST_F(WebRtcVideoChannelBaseTest,RequestEncoderSwitchIncorrectParam)2329 TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchIncorrectParam) {
2330 const std::string kParam = "the-param";
2331 const std::string kPing = "ping";
2332 const std::string kPong = "pong";
2333
2334 cricket::VideoSendParameters parameters;
2335 VideoCodec vp9 = GetEngineCodec("VP9");
2336 vp9.params[kParam] = kPong;
2337 parameters.codecs.push_back(vp9);
2338
2339 VideoCodec vp8 = GetEngineCodec("VP8");
2340 vp8.params[kParam] = kPing;
2341 parameters.codecs.push_back(vp8);
2342
2343 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2344 channel_->SetVideoCodecSwitchingEnabled(true);
2345
2346 VideoCodec codec;
2347 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2348 EXPECT_THAT(codec.name, Eq("VP9"));
2349
2350 // RequestEncoderSwitch will post a task to the worker thread (which is also
2351 // the current thread), hence the ProcessMessages call.
2352 webrtc::EncoderSwitchRequestCallback::Config conf1{"VP8", kParam, kPing};
2353 channel_->RequestEncoderSwitch(conf1);
2354 rtc::Thread::Current()->ProcessMessages(30);
2355 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2356 EXPECT_THAT(codec.name, Eq("VP8"));
2357 EXPECT_THAT(codec.params, Contains(Pair(kParam, kPing)));
2358
2359 // Incorrect conf2.value, expect no codec switch.
2360 webrtc::EncoderSwitchRequestCallback::Config conf2{"VP9", kParam, kPing};
2361 channel_->RequestEncoderSwitch(conf2);
2362 rtc::Thread::Current()->ProcessMessages(30);
2363 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2364 EXPECT_THAT(codec.name, Eq("VP8"));
2365 EXPECT_THAT(codec.params, Contains(Pair(kParam, kPing)));
2366 }
2367
TEST_F(WebRtcVideoChannelBaseTest,RequestEncoderSwitchWithConfigBeforeEnabling)2368 TEST_F(WebRtcVideoChannelBaseTest,
2369 RequestEncoderSwitchWithConfigBeforeEnabling) {
2370 const std::string kParam = "the-param";
2371 const std::string kPing = "ping";
2372 const std::string kPong = "pong";
2373
2374 cricket::VideoSendParameters parameters;
2375 VideoCodec vp9 = GetEngineCodec("VP9");
2376 vp9.params[kParam] = kPong;
2377 parameters.codecs.push_back(vp9);
2378
2379 VideoCodec vp8 = GetEngineCodec("VP8");
2380 vp8.params[kParam] = kPing;
2381 parameters.codecs.push_back(vp8);
2382
2383 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2384
2385 VideoCodec codec;
2386 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2387 EXPECT_THAT(codec.name, Eq("VP9"));
2388
2389 webrtc::EncoderSwitchRequestCallback::Config conf{"VP8", kParam, kPing};
2390 channel_->RequestEncoderSwitch(conf);
2391
2392 // Enable codec switching after it has been requested.
2393 channel_->SetVideoCodecSwitchingEnabled(true);
2394
2395 // RequestEncoderSwitch will post a task to the worker thread (which is also
2396 // the current thread), hence the ProcessMessages call.
2397 rtc::Thread::Current()->ProcessMessages(30);
2398 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2399 EXPECT_THAT(codec.name, Eq("VP8"));
2400 EXPECT_THAT(codec.params, Contains(Pair(kParam, kPing)));
2401 }
2402
2403 #endif // defined(RTC_ENABLE_VP9)
2404
2405 class WebRtcVideoChannelTest : public WebRtcVideoEngineTest {
2406 public:
WebRtcVideoChannelTest()2407 WebRtcVideoChannelTest() : WebRtcVideoChannelTest("") {}
WebRtcVideoChannelTest(const char * field_trials)2408 explicit WebRtcVideoChannelTest(const char* field_trials)
2409 : WebRtcVideoEngineTest(field_trials),
2410 frame_source_(1280, 720, rtc::kNumMicrosecsPerSec / 30),
2411 last_ssrc_(0) {}
SetUp()2412 void SetUp() override {
2413 AddSupportedVideoCodecType("VP8");
2414 AddSupportedVideoCodecType("VP9");
2415 #if defined(WEBRTC_USE_H264)
2416 AddSupportedVideoCodecType("H264");
2417 #endif
2418
2419 fake_call_.reset(new FakeCall());
2420 channel_.reset(engine_.CreateMediaChannel(
2421 fake_call_.get(), GetMediaConfig(), VideoOptions(),
2422 webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()));
2423 channel_->OnReadyToSend(true);
2424 last_ssrc_ = 123;
2425 send_parameters_.codecs = engine_.send_codecs();
2426 recv_parameters_.codecs = engine_.recv_codecs();
2427 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
2428 }
2429
GetEngineCodec(const std::string & name)2430 cricket::VideoCodec GetEngineCodec(const std::string& name) {
2431 for (const cricket::VideoCodec& engine_codec : engine_.send_codecs()) {
2432 if (absl::EqualsIgnoreCase(name, engine_codec.name))
2433 return engine_codec;
2434 }
2435 // This point should never be reached.
2436 ADD_FAILURE() << "Unrecognized codec name: " << name;
2437 return cricket::VideoCodec();
2438 }
2439
DefaultCodec()2440 cricket::VideoCodec DefaultCodec() { return GetEngineCodec("VP8"); }
2441
2442 protected:
AddSendStream()2443 FakeVideoSendStream* AddSendStream() {
2444 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
2445 }
2446
AddSendStream(const StreamParams & sp)2447 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
2448 size_t num_streams = fake_call_->GetVideoSendStreams().size();
2449 EXPECT_TRUE(channel_->AddSendStream(sp));
2450 std::vector<FakeVideoSendStream*> streams =
2451 fake_call_->GetVideoSendStreams();
2452 EXPECT_EQ(num_streams + 1, streams.size());
2453 return streams[streams.size() - 1];
2454 }
2455
GetFakeSendStreams()2456 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
2457 return fake_call_->GetVideoSendStreams();
2458 }
2459
AddRecvStream()2460 FakeVideoReceiveStream* AddRecvStream() {
2461 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
2462 }
2463
AddRecvStream(const StreamParams & sp)2464 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
2465 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
2466 EXPECT_TRUE(channel_->AddRecvStream(sp));
2467 std::vector<FakeVideoReceiveStream*> streams =
2468 fake_call_->GetVideoReceiveStreams();
2469 EXPECT_EQ(num_streams + 1, streams.size());
2470 return streams[streams.size() - 1];
2471 }
2472
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)2473 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
2474 int expected_min_bitrate_bps,
2475 const char* start_bitrate_kbps,
2476 int expected_start_bitrate_bps,
2477 const char* max_bitrate_kbps,
2478 int expected_max_bitrate_bps) {
2479 ExpectSetBitrateParameters(expected_min_bitrate_bps,
2480 expected_start_bitrate_bps,
2481 expected_max_bitrate_bps);
2482 auto& codecs = send_parameters_.codecs;
2483 codecs.clear();
2484 codecs.push_back(GetEngineCodec("VP8"));
2485 codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps;
2486 codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps;
2487 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps;
2488 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2489 }
2490
ExpectSetBitrateParameters(int min_bitrate_bps,int start_bitrate_bps,int max_bitrate_bps)2491 void ExpectSetBitrateParameters(int min_bitrate_bps,
2492 int start_bitrate_bps,
2493 int max_bitrate_bps) {
2494 EXPECT_CALL(
2495 *fake_call_->GetMockTransportControllerSend(),
2496 SetSdpBitrateParameters(AllOf(
2497 Field(&BitrateConstraints::min_bitrate_bps, min_bitrate_bps),
2498 Field(&BitrateConstraints::start_bitrate_bps, start_bitrate_bps),
2499 Field(&BitrateConstraints::max_bitrate_bps, max_bitrate_bps))));
2500 }
2501
ExpectSetMaxBitrate(int max_bitrate_bps)2502 void ExpectSetMaxBitrate(int max_bitrate_bps) {
2503 EXPECT_CALL(*fake_call_->GetMockTransportControllerSend(),
2504 SetSdpBitrateParameters(Field(
2505 &BitrateConstraints::max_bitrate_bps, max_bitrate_bps)));
2506 }
2507
TestExtmapAllowMixedCaller(bool extmap_allow_mixed)2508 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
2509 // For a caller, the answer will be applied in set remote description
2510 // where SetSendParameters() is called.
2511 EXPECT_TRUE(
2512 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
2513 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
2514 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2515 const webrtc::VideoSendStream::Config& config =
2516 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2517 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
2518 }
2519
TestExtmapAllowMixedCallee(bool extmap_allow_mixed)2520 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
2521 // For a callee, the answer will be applied in set local description
2522 // where SetExtmapAllowMixed() and AddSendStream() are called.
2523 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
2524 EXPECT_TRUE(
2525 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
2526 const webrtc::VideoSendStream::Config& config =
2527 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2528 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
2529 }
2530
TestSetSendRtpHeaderExtensions(const std::string & ext_uri)2531 void TestSetSendRtpHeaderExtensions(const std::string& ext_uri) {
2532 // Enable extension.
2533 const int id = 1;
2534 cricket::VideoSendParameters parameters = send_parameters_;
2535 parameters.extensions.push_back(RtpExtension(ext_uri, id));
2536 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2537 FakeVideoSendStream* send_stream =
2538 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2539
2540 // Verify the send extension id.
2541 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2542 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
2543 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
2544 // Verify call with same set of extensions returns true.
2545 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2546 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
2547 // receivers.
2548 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
2549 ->GetConfig()
2550 .rtp.extensions.empty());
2551
2552 // Verify that existing RTP header extensions can be removed.
2553 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2554 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2555 send_stream = fake_call_->GetVideoSendStreams()[0];
2556 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
2557
2558 // Verify that adding receive RTP header extensions adds them for existing
2559 // streams.
2560 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2561 send_stream = fake_call_->GetVideoSendStreams()[0];
2562 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2563 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
2564 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
2565 }
2566
TestSetRecvRtpHeaderExtensions(const std::string & ext_uri)2567 void TestSetRecvRtpHeaderExtensions(const std::string& ext_uri) {
2568 // Enable extension.
2569 const int id = 1;
2570 cricket::VideoRecvParameters parameters = recv_parameters_;
2571 parameters.extensions.push_back(RtpExtension(ext_uri, id));
2572 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2573
2574 FakeVideoReceiveStream* recv_stream =
2575 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2576
2577 // Verify the recv extension id.
2578 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
2579 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
2580 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
2581 // Verify call with same set of extensions returns true.
2582 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2583
2584 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
2585 // senders.
2586 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
2587 ->GetConfig()
2588 .rtp.extensions.empty());
2589
2590 // Verify that existing RTP header extensions can be removed.
2591 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
2592 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
2593 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
2594 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
2595
2596 // Verify that adding receive RTP header extensions adds them for existing
2597 // streams.
2598 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
2599 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
2600 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
2601 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
2602 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
2603 }
2604
TestLossNotificationState(bool expect_lntf_enabled)2605 void TestLossNotificationState(bool expect_lntf_enabled) {
2606 AssignDefaultCodec();
2607 VerifyCodecHasDefaultFeedbackParams(default_codec_, expect_lntf_enabled);
2608
2609 cricket::VideoSendParameters parameters;
2610 parameters.codecs = engine_.send_codecs();
2611 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2612 EXPECT_TRUE(channel_->SetSend(true));
2613
2614 // Send side.
2615 FakeVideoSendStream* send_stream =
2616 AddSendStream(cricket::StreamParams::CreateLegacy(1));
2617 EXPECT_EQ(send_stream->GetConfig().rtp.lntf.enabled, expect_lntf_enabled);
2618
2619 // Receiver side.
2620 FakeVideoReceiveStream* recv_stream =
2621 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
2622 EXPECT_EQ(recv_stream->GetConfig().rtp.lntf.enabled, expect_lntf_enabled);
2623 }
2624
TestExtensionFilter(const std::vector<std::string> & extensions,const std::string & expected_extension)2625 void TestExtensionFilter(const std::vector<std::string>& extensions,
2626 const std::string& expected_extension) {
2627 cricket::VideoSendParameters parameters = send_parameters_;
2628 int expected_id = -1;
2629 int id = 1;
2630 for (const std::string& extension : extensions) {
2631 if (extension == expected_extension)
2632 expected_id = id;
2633 parameters.extensions.push_back(RtpExtension(extension, id++));
2634 }
2635 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2636 FakeVideoSendStream* send_stream =
2637 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2638
2639 // Verify that only one of them has been set, and that it is the one with
2640 // highest priority (transport sequence number).
2641 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2642 EXPECT_EQ(expected_id, send_stream->GetConfig().rtp.extensions[0].id);
2643 EXPECT_EQ(expected_extension,
2644 send_stream->GetConfig().rtp.extensions[0].uri);
2645 }
2646
2647 void TestDegradationPreference(bool resolution_scaling_enabled,
2648 bool fps_scaling_enabled);
2649
2650 void TestCpuAdaptation(bool enable_overuse, bool is_screenshare);
2651 void TestReceiverLocalSsrcConfiguration(bool receiver_first);
2652 void TestReceiveUnsignaledSsrcPacket(uint8_t payload_type,
2653 bool expect_created_receive_stream);
2654
SetDenoisingOption(uint32_t ssrc,webrtc::test::FrameForwarder * frame_forwarder,bool enabled)2655 FakeVideoSendStream* SetDenoisingOption(
2656 uint32_t ssrc,
2657 webrtc::test::FrameForwarder* frame_forwarder,
2658 bool enabled) {
2659 cricket::VideoOptions options;
2660 options.video_noise_reduction = enabled;
2661 EXPECT_TRUE(channel_->SetVideoSend(ssrc, &options, frame_forwarder));
2662 // Options only take effect on the next frame.
2663 frame_forwarder->IncomingCapturedFrame(frame_source_.GetFrame());
2664
2665 return fake_call_->GetVideoSendStreams().back();
2666 }
2667
SetUpSimulcast(bool enabled,bool with_rtx)2668 FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) {
2669 const int kRtxSsrcOffset = 0xDEADBEEF;
2670 last_ssrc_ += 3;
2671 std::vector<uint32_t> ssrcs;
2672 std::vector<uint32_t> rtx_ssrcs;
2673 uint32_t num_streams = enabled ? 3 : 1;
2674 for (uint32_t i = 0; i < num_streams; ++i) {
2675 uint32_t ssrc = last_ssrc_ + i;
2676 ssrcs.push_back(ssrc);
2677 if (with_rtx) {
2678 rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset);
2679 }
2680 }
2681 if (with_rtx) {
2682 return AddSendStream(
2683 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
2684 }
2685 return AddSendStream(CreateSimStreamParams("cname", ssrcs));
2686 }
2687
GetMaxEncoderBitrate()2688 int GetMaxEncoderBitrate() {
2689 std::vector<FakeVideoSendStream*> streams =
2690 fake_call_->GetVideoSendStreams();
2691 EXPECT_EQ(1u, streams.size());
2692 FakeVideoSendStream* stream = streams[streams.size() - 1];
2693 EXPECT_EQ(1u, stream->GetEncoderConfig().number_of_streams);
2694 return stream->GetVideoStreams()[0].max_bitrate_bps;
2695 }
2696
SetAndExpectMaxBitrate(int global_max,int stream_max,int expected_encoder_bitrate)2697 void SetAndExpectMaxBitrate(int global_max,
2698 int stream_max,
2699 int expected_encoder_bitrate) {
2700 VideoSendParameters limited_send_params = send_parameters_;
2701 limited_send_params.max_bandwidth_bps = global_max;
2702 EXPECT_TRUE(channel_->SetSendParameters(limited_send_params));
2703 webrtc::RtpParameters parameters =
2704 channel_->GetRtpSendParameters(last_ssrc_);
2705 EXPECT_EQ(1UL, parameters.encodings.size());
2706 parameters.encodings[0].max_bitrate_bps = stream_max;
2707 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
2708 // Read back the parameteres and verify they have the correct value
2709 parameters = channel_->GetRtpSendParameters(last_ssrc_);
2710 EXPECT_EQ(1UL, parameters.encodings.size());
2711 EXPECT_EQ(stream_max, parameters.encodings[0].max_bitrate_bps);
2712 // Verify that the new value propagated down to the encoder
2713 EXPECT_EQ(expected_encoder_bitrate, GetMaxEncoderBitrate());
2714 }
2715
2716 // Values from kSimulcastConfigs in simulcast.cc.
GetSimulcastBitrates720p() const2717 const std::vector<webrtc::VideoStream> GetSimulcastBitrates720p() const {
2718 std::vector<webrtc::VideoStream> layers(3);
2719 layers[0].min_bitrate_bps = 30000;
2720 layers[0].target_bitrate_bps = 150000;
2721 layers[0].max_bitrate_bps = 200000;
2722 layers[1].min_bitrate_bps = 150000;
2723 layers[1].target_bitrate_bps = 500000;
2724 layers[1].max_bitrate_bps = 700000;
2725 layers[2].min_bitrate_bps = 600000;
2726 layers[2].target_bitrate_bps = 2500000;
2727 layers[2].max_bitrate_bps = 2500000;
2728 return layers;
2729 }
2730
2731 cricket::FakeFrameSource frame_source_;
2732 std::unique_ptr<FakeCall> fake_call_;
2733 std::unique_ptr<VideoMediaChannel> channel_;
2734 cricket::VideoSendParameters send_parameters_;
2735 cricket::VideoRecvParameters recv_parameters_;
2736 uint32_t last_ssrc_;
2737 };
2738
TEST_F(WebRtcVideoChannelTest,SetsSyncGroupFromSyncLabel)2739 TEST_F(WebRtcVideoChannelTest, SetsSyncGroupFromSyncLabel) {
2740 const uint32_t kVideoSsrc = 123;
2741 const std::string kSyncLabel = "AvSyncLabel";
2742
2743 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc);
2744 sp.set_stream_ids({kSyncLabel});
2745 EXPECT_TRUE(channel_->AddRecvStream(sp));
2746
2747 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
2748 EXPECT_EQ(kSyncLabel,
2749 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group)
2750 << "SyncGroup should be set based on sync_label";
2751 }
2752
TEST_F(WebRtcVideoChannelTest,RecvStreamWithSimAndRtx)2753 TEST_F(WebRtcVideoChannelTest, RecvStreamWithSimAndRtx) {
2754 cricket::VideoSendParameters parameters;
2755 parameters.codecs = engine_.send_codecs();
2756 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2757 EXPECT_TRUE(channel_->SetSend(true));
2758 parameters.conference_mode = true;
2759 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2760
2761 // Send side.
2762 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
2763 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
2764 FakeVideoSendStream* send_stream = AddSendStream(
2765 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
2766
2767 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
2768 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
2769 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
2770
2771 // Receiver side.
2772 FakeVideoReceiveStream* recv_stream = AddRecvStream(
2773 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
2774 EXPECT_FALSE(
2775 recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
2776 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
2777 << "RTX should be mapped for all decoders/payload types.";
2778 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
2779 GetEngineCodec("red").id))
2780 << "RTX should be mapped for the RED payload type";
2781
2782 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
2783 }
2784
TEST_F(WebRtcVideoChannelTest,RecvStreamWithRtx)2785 TEST_F(WebRtcVideoChannelTest, RecvStreamWithRtx) {
2786 // Setup one channel with an associated RTX stream.
2787 cricket::StreamParams params =
2788 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2789 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
2790 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
2791 EXPECT_EQ(kRtxSsrcs1[0], recv_stream->GetConfig().rtp.rtx_ssrc);
2792
2793 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
2794 << "RTX should be mapped for all decoders/payload types.";
2795 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
2796 GetEngineCodec("red").id))
2797 << "RTX should be mapped for the RED payload type";
2798 }
2799
TEST_F(WebRtcVideoChannelTest,RecvStreamNoRtx)2800 TEST_F(WebRtcVideoChannelTest, RecvStreamNoRtx) {
2801 // Setup one channel without an associated RTX stream.
2802 cricket::StreamParams params =
2803 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2804 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
2805 ASSERT_EQ(0U, recv_stream->GetConfig().rtp.rtx_ssrc);
2806 }
2807
2808 // Test propagation of extmap allow mixed setting.
TEST_F(WebRtcVideoChannelTest,SetExtmapAllowMixedAsCaller)2809 TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCaller) {
2810 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2811 }
TEST_F(WebRtcVideoChannelTest,SetExtmapAllowMixedDisabledAsCaller)2812 TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCaller) {
2813 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2814 }
TEST_F(WebRtcVideoChannelTest,SetExtmapAllowMixedAsCallee)2815 TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCallee) {
2816 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2817 }
TEST_F(WebRtcVideoChannelTest,SetExtmapAllowMixedDisabledAsCallee)2818 TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCallee) {
2819 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2820 }
2821
TEST_F(WebRtcVideoChannelTest,NoHeaderExtesionsByDefault)2822 TEST_F(WebRtcVideoChannelTest, NoHeaderExtesionsByDefault) {
2823 FakeVideoSendStream* send_stream =
2824 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
2825 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
2826
2827 FakeVideoReceiveStream* recv_stream =
2828 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
2829 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
2830 }
2831
2832 // Test support for RTP timestamp offset header extension.
TEST_F(WebRtcVideoChannelTest,SendRtpTimestampOffsetHeaderExtensions)2833 TEST_F(WebRtcVideoChannelTest, SendRtpTimestampOffsetHeaderExtensions) {
2834 TestSetSendRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
2835 }
2836
TEST_F(WebRtcVideoChannelTest,RecvRtpTimestampOffsetHeaderExtensions)2837 TEST_F(WebRtcVideoChannelTest, RecvRtpTimestampOffsetHeaderExtensions) {
2838 TestSetRecvRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
2839 }
2840
2841 // Test support for absolute send time header extension.
TEST_F(WebRtcVideoChannelTest,SendAbsoluteSendTimeHeaderExtensions)2842 TEST_F(WebRtcVideoChannelTest, SendAbsoluteSendTimeHeaderExtensions) {
2843 TestSetSendRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
2844 }
2845
TEST_F(WebRtcVideoChannelTest,RecvAbsoluteSendTimeHeaderExtensions)2846 TEST_F(WebRtcVideoChannelTest, RecvAbsoluteSendTimeHeaderExtensions) {
2847 TestSetRecvRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
2848 }
2849
TEST_F(WebRtcVideoChannelTest,FiltersExtensionsPicksTransportSeqNum)2850 TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksTransportSeqNum) {
2851 webrtc::test::ScopedFieldTrials override_field_trials_(
2852 "WebRTC-FilterAbsSendTimeExtension/Enabled/");
2853 // Enable three redundant extensions.
2854 std::vector<std::string> extensions;
2855 extensions.push_back(RtpExtension::kAbsSendTimeUri);
2856 extensions.push_back(RtpExtension::kTimestampOffsetUri);
2857 extensions.push_back(RtpExtension::kTransportSequenceNumberUri);
2858 TestExtensionFilter(extensions, RtpExtension::kTransportSequenceNumberUri);
2859 }
2860
TEST_F(WebRtcVideoChannelTest,FiltersExtensionsPicksAbsSendTime)2861 TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksAbsSendTime) {
2862 // Enable two redundant extensions.
2863 std::vector<std::string> extensions;
2864 extensions.push_back(RtpExtension::kAbsSendTimeUri);
2865 extensions.push_back(RtpExtension::kTimestampOffsetUri);
2866 TestExtensionFilter(extensions, RtpExtension::kAbsSendTimeUri);
2867 }
2868
2869 // Test support for transport sequence number header extension.
TEST_F(WebRtcVideoChannelTest,SendTransportSequenceNumberHeaderExtensions)2870 TEST_F(WebRtcVideoChannelTest, SendTransportSequenceNumberHeaderExtensions) {
2871 TestSetSendRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
2872 }
TEST_F(WebRtcVideoChannelTest,RecvTransportSequenceNumberHeaderExtensions)2873 TEST_F(WebRtcVideoChannelTest, RecvTransportSequenceNumberHeaderExtensions) {
2874 TestSetRecvRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
2875 }
2876
2877 // Test support for video rotation header extension.
TEST_F(WebRtcVideoChannelTest,SendVideoRotationHeaderExtensions)2878 TEST_F(WebRtcVideoChannelTest, SendVideoRotationHeaderExtensions) {
2879 TestSetSendRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
2880 }
TEST_F(WebRtcVideoChannelTest,RecvVideoRotationHeaderExtensions)2881 TEST_F(WebRtcVideoChannelTest, RecvVideoRotationHeaderExtensions) {
2882 TestSetRecvRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
2883 }
2884
TEST_F(WebRtcVideoChannelTest,IdenticalSendExtensionsDoesntRecreateStream)2885 TEST_F(WebRtcVideoChannelTest, IdenticalSendExtensionsDoesntRecreateStream) {
2886 const int kAbsSendTimeId = 1;
2887 const int kVideoRotationId = 2;
2888 send_parameters_.extensions.push_back(
2889 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
2890 send_parameters_.extensions.push_back(
2891 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
2892
2893 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2894 FakeVideoSendStream* send_stream =
2895 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2896
2897 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2898 ASSERT_EQ(2u, send_stream->GetConfig().rtp.extensions.size());
2899
2900 // Setting the same extensions (even if in different order) shouldn't
2901 // reallocate the stream.
2902 absl::c_reverse(send_parameters_.extensions);
2903 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2904
2905 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2906
2907 // Setting different extensions should recreate the stream.
2908 send_parameters_.extensions.resize(1);
2909 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2910
2911 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
2912 }
2913
TEST_F(WebRtcVideoChannelTest,IdenticalRecvExtensionsDoesntRecreateStream)2914 TEST_F(WebRtcVideoChannelTest, IdenticalRecvExtensionsDoesntRecreateStream) {
2915 const int kTOffsetId = 1;
2916 const int kAbsSendTimeId = 2;
2917 const int kVideoRotationId = 3;
2918 recv_parameters_.extensions.push_back(
2919 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
2920 recv_parameters_.extensions.push_back(
2921 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
2922 recv_parameters_.extensions.push_back(
2923 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
2924
2925 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
2926 FakeVideoReceiveStream* recv_stream =
2927 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2928
2929 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2930 ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size());
2931
2932 // Setting the same extensions (even if in different order) shouldn't
2933 // reallocate the stream.
2934 absl::c_reverse(recv_parameters_.extensions);
2935 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
2936
2937 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2938
2939 // Setting different extensions should recreate the stream.
2940 recv_parameters_.extensions.resize(1);
2941 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
2942
2943 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
2944 }
2945
TEST_F(WebRtcVideoChannelTest,SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions)2946 TEST_F(WebRtcVideoChannelTest,
2947 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
2948 const int kUnsupportedId = 1;
2949 const int kTOffsetId = 2;
2950
2951 send_parameters_.extensions.push_back(
2952 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
2953 send_parameters_.extensions.push_back(
2954 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
2955 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2956 FakeVideoSendStream* send_stream =
2957 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2958
2959 // Only timestamp offset extension is set to send stream,
2960 // unsupported rtp extension is ignored.
2961 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2962 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
2963 send_stream->GetConfig().rtp.extensions[0].uri.c_str());
2964 }
2965
TEST_F(WebRtcVideoChannelTest,SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions)2966 TEST_F(WebRtcVideoChannelTest,
2967 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
2968 const int kUnsupportedId = 1;
2969 const int kTOffsetId = 2;
2970
2971 recv_parameters_.extensions.push_back(
2972 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
2973 recv_parameters_.extensions.push_back(
2974 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
2975 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
2976 FakeVideoReceiveStream* recv_stream =
2977 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2978
2979 // Only timestamp offset extension is set to receive stream,
2980 // unsupported rtp extension is ignored.
2981 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
2982 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
2983 recv_stream->GetConfig().rtp.extensions[0].uri.c_str());
2984 }
2985
TEST_F(WebRtcVideoChannelTest,SetSendRtpHeaderExtensionsRejectsIncorrectIds)2986 TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
2987 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
2988 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
2989 send_parameters_.extensions.push_back(
2990 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
2991 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_))
2992 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
2993 }
2994 }
2995
TEST_F(WebRtcVideoChannelTest,SetRecvRtpHeaderExtensionsRejectsIncorrectIds)2996 TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
2997 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
2998 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
2999 recv_parameters_.extensions.push_back(
3000 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
3001 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_))
3002 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
3003 }
3004 }
3005
TEST_F(WebRtcVideoChannelTest,SetSendRtpHeaderExtensionsRejectsDuplicateIds)3006 TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
3007 const int id = 1;
3008 send_parameters_.extensions.push_back(
3009 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
3010 send_parameters_.extensions.push_back(
3011 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
3012 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
3013
3014 // Duplicate entries are also not supported.
3015 send_parameters_.extensions.clear();
3016 send_parameters_.extensions.push_back(
3017 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
3018 send_parameters_.extensions.push_back(send_parameters_.extensions.back());
3019 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
3020 }
3021
TEST_F(WebRtcVideoChannelTest,SetRecvRtpHeaderExtensionsRejectsDuplicateIds)3022 TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
3023 const int id = 1;
3024 recv_parameters_.extensions.push_back(
3025 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
3026 recv_parameters_.extensions.push_back(
3027 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
3028 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
3029
3030 // Duplicate entries are also not supported.
3031 recv_parameters_.extensions.clear();
3032 recv_parameters_.extensions.push_back(
3033 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
3034 recv_parameters_.extensions.push_back(recv_parameters_.extensions.back());
3035 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
3036 }
3037
TEST_F(WebRtcVideoChannelTest,AddRecvStreamOnlyUsesOneReceiveStream)3038 TEST_F(WebRtcVideoChannelTest, AddRecvStreamOnlyUsesOneReceiveStream) {
3039 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
3040 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
3041 }
3042
TEST_F(WebRtcVideoChannelTest,RtcpIsCompoundByDefault)3043 TEST_F(WebRtcVideoChannelTest, RtcpIsCompoundByDefault) {
3044 FakeVideoReceiveStream* stream = AddRecvStream();
3045 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream->GetConfig().rtp.rtcp_mode);
3046 }
3047
TEST_F(WebRtcVideoChannelTest,TransportCcIsEnabledByDefault)3048 TEST_F(WebRtcVideoChannelTest, TransportCcIsEnabledByDefault) {
3049 FakeVideoReceiveStream* stream = AddRecvStream();
3050 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
3051 }
3052
TEST_F(WebRtcVideoChannelTest,TransportCcCanBeEnabledAndDisabled)3053 TEST_F(WebRtcVideoChannelTest, TransportCcCanBeEnabledAndDisabled) {
3054 FakeVideoReceiveStream* stream = AddRecvStream();
3055 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
3056
3057 // Verify that transport cc feedback is turned off when send(!) codecs without
3058 // transport cc feedback are set.
3059 cricket::VideoSendParameters parameters;
3060 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
3061 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
3062 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3063 stream = fake_call_->GetVideoReceiveStreams()[0];
3064 EXPECT_FALSE(stream->GetConfig().rtp.transport_cc);
3065
3066 // Verify that transport cc feedback is turned on when setting default codecs
3067 // since the default codecs have transport cc feedback enabled.
3068 parameters.codecs = engine_.send_codecs();
3069 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3070 stream = fake_call_->GetVideoReceiveStreams()[0];
3071 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
3072 }
3073
TEST_F(WebRtcVideoChannelTest,LossNotificationIsDisabledByDefault)3074 TEST_F(WebRtcVideoChannelTest, LossNotificationIsDisabledByDefault) {
3075 TestLossNotificationState(false);
3076 }
3077
TEST_F(WebRtcVideoChannelTest,LossNotificationIsEnabledByFieldTrial)3078 TEST_F(WebRtcVideoChannelTest, LossNotificationIsEnabledByFieldTrial) {
3079 RTC_DCHECK(!override_field_trials_);
3080 override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>(
3081 "WebRTC-RtcpLossNotification/Enabled/");
3082 SetUp();
3083 TestLossNotificationState(true);
3084 }
3085
TEST_F(WebRtcVideoChannelTest,LossNotificationCanBeEnabledAndDisabled)3086 TEST_F(WebRtcVideoChannelTest, LossNotificationCanBeEnabledAndDisabled) {
3087 RTC_DCHECK(!override_field_trials_);
3088 override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>(
3089 "WebRTC-RtcpLossNotification/Enabled/");
3090 SetUp();
3091
3092 AssignDefaultCodec();
3093 VerifyCodecHasDefaultFeedbackParams(default_codec_, true);
3094
3095 {
3096 cricket::VideoSendParameters parameters;
3097 parameters.codecs = engine_.send_codecs();
3098 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3099 EXPECT_TRUE(channel_->SetSend(true));
3100 }
3101
3102 // Start with LNTF enabled.
3103 FakeVideoSendStream* send_stream =
3104 AddSendStream(cricket::StreamParams::CreateLegacy(1));
3105 ASSERT_TRUE(send_stream->GetConfig().rtp.lntf.enabled);
3106 FakeVideoReceiveStream* recv_stream =
3107 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
3108 ASSERT_TRUE(recv_stream->GetConfig().rtp.lntf.enabled);
3109
3110 // Verify that LNTF is turned off when send(!) codecs without LNTF are set.
3111 cricket::VideoSendParameters parameters;
3112 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
3113 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
3114 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3115 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
3116 EXPECT_FALSE(recv_stream->GetConfig().rtp.lntf.enabled);
3117 send_stream = fake_call_->GetVideoSendStreams()[0];
3118 EXPECT_FALSE(send_stream->GetConfig().rtp.lntf.enabled);
3119
3120 // Setting the default codecs again, including VP8, turns LNTF back on.
3121 parameters.codecs = engine_.send_codecs();
3122 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3123 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
3124 EXPECT_TRUE(recv_stream->GetConfig().rtp.lntf.enabled);
3125 send_stream = fake_call_->GetVideoSendStreams()[0];
3126 EXPECT_TRUE(send_stream->GetConfig().rtp.lntf.enabled);
3127 }
3128
TEST_F(WebRtcVideoChannelTest,NackIsEnabledByDefault)3129 TEST_F(WebRtcVideoChannelTest, NackIsEnabledByDefault) {
3130 AssignDefaultCodec();
3131 VerifyCodecHasDefaultFeedbackParams(default_codec_, false);
3132
3133 cricket::VideoSendParameters parameters;
3134 parameters.codecs = engine_.send_codecs();
3135 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3136 EXPECT_TRUE(channel_->SetSend(true));
3137
3138 // Send side.
3139 FakeVideoSendStream* send_stream =
3140 AddSendStream(cricket::StreamParams::CreateLegacy(1));
3141 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
3142
3143 // Receiver side.
3144 FakeVideoReceiveStream* recv_stream =
3145 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
3146 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
3147
3148 // Nack history size should match between sender and receiver.
3149 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
3150 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
3151 }
3152
TEST_F(WebRtcVideoChannelTest,NackCanBeEnabledAndDisabled)3153 TEST_F(WebRtcVideoChannelTest, NackCanBeEnabledAndDisabled) {
3154 FakeVideoSendStream* send_stream = AddSendStream();
3155 FakeVideoReceiveStream* recv_stream = AddRecvStream();
3156
3157 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
3158 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
3159
3160 // Verify that NACK is turned off when send(!) codecs without NACK are set.
3161 cricket::VideoSendParameters parameters;
3162 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
3163 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
3164 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3165 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
3166 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
3167 send_stream = fake_call_->GetVideoSendStreams()[0];
3168 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
3169
3170 // Verify that NACK is turned on when setting default codecs since the
3171 // default codecs have NACK enabled.
3172 parameters.codecs = engine_.send_codecs();
3173 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3174 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
3175 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
3176 send_stream = fake_call_->GetVideoSendStreams()[0];
3177 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
3178 }
3179
3180 // This test verifies that new frame sizes reconfigures encoders even though not
3181 // (yet) sending. The purpose of this is to permit encoding as quickly as
3182 // possible once we start sending. Likely the frames being input are from the
3183 // same source that will be sent later, which just means that we're ready
3184 // earlier.
TEST_F(WebRtcVideoChannelTest,ReconfiguresEncodersWhenNotSending)3185 TEST_F(WebRtcVideoChannelTest, ReconfiguresEncodersWhenNotSending) {
3186 cricket::VideoSendParameters parameters;
3187 parameters.codecs.push_back(GetEngineCodec("VP8"));
3188 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3189 channel_->SetSend(false);
3190
3191 FakeVideoSendStream* stream = AddSendStream();
3192
3193 // No frames entered.
3194 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
3195 EXPECT_EQ(0u, streams[0].width);
3196 EXPECT_EQ(0u, streams[0].height);
3197
3198 webrtc::test::FrameForwarder frame_forwarder;
3199 cricket::FakeFrameSource frame_source(1280, 720,
3200 rtc::kNumMicrosecsPerSec / 30);
3201
3202 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
3203 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
3204
3205 // Frame entered, should be reconfigured to new dimensions.
3206 streams = stream->GetVideoStreams();
3207 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams[0].width);
3208 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams[0].height);
3209
3210 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
3211 }
3212
TEST_F(WebRtcVideoChannelTest,UsesCorrectSettingsForScreencast)3213 TEST_F(WebRtcVideoChannelTest, UsesCorrectSettingsForScreencast) {
3214 static const int kScreenshareMinBitrateKbps = 800;
3215 cricket::VideoCodec codec = GetEngineCodec("VP8");
3216 cricket::VideoSendParameters parameters;
3217 parameters.codecs.push_back(codec);
3218 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3219 AddSendStream();
3220
3221 webrtc::test::FrameForwarder frame_forwarder;
3222 cricket::FakeFrameSource frame_source(1280, 720,
3223 rtc::kNumMicrosecsPerSec / 30);
3224 VideoOptions min_bitrate_options;
3225 min_bitrate_options.screencast_min_bitrate_kbps = kScreenshareMinBitrateKbps;
3226 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &min_bitrate_options,
3227 &frame_forwarder));
3228
3229 EXPECT_TRUE(channel_->SetSend(true));
3230
3231 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
3232 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
3233 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3234
3235 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
3236
3237 // Verify non-screencast settings.
3238 webrtc::VideoEncoderConfig encoder_config =
3239 send_stream->GetEncoderConfig().Copy();
3240 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
3241 encoder_config.content_type);
3242 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
3243 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams.front().width);
3244 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams.front().height);
3245 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
3246 << "Non-screenshare shouldn't use min-transmit bitrate.";
3247
3248 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
3249 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
3250 VideoOptions screencast_options;
3251 screencast_options.is_screencast = true;
3252 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &screencast_options,
3253 &frame_forwarder));
3254 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
3255 // Send stream recreated after option change.
3256 ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
3257 send_stream = fake_call_->GetVideoSendStreams().front();
3258 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
3259
3260 // Verify screencast settings.
3261 encoder_config = send_stream->GetEncoderConfig().Copy();
3262 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
3263 encoder_config.content_type);
3264 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
3265 encoder_config.min_transmit_bitrate_bps);
3266
3267 streams = send_stream->GetVideoStreams();
3268 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams.front().width);
3269 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams.front().height);
3270 EXPECT_FALSE(streams[0].num_temporal_layers.has_value());
3271 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
3272 }
3273
TEST_F(WebRtcVideoChannelTest,ConferenceModeScreencastConfiguresTemporalLayer)3274 TEST_F(WebRtcVideoChannelTest,
3275 ConferenceModeScreencastConfiguresTemporalLayer) {
3276 static const int kConferenceScreencastTemporalBitrateBps = 200 * 1000;
3277 send_parameters_.conference_mode = true;
3278 channel_->SetSendParameters(send_parameters_);
3279
3280 AddSendStream();
3281 VideoOptions options;
3282 options.is_screencast = true;
3283 webrtc::test::FrameForwarder frame_forwarder;
3284 cricket::FakeFrameSource frame_source(1280, 720,
3285 rtc::kNumMicrosecsPerSec / 30);
3286 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3287 EXPECT_TRUE(channel_->SetSend(true));
3288
3289 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
3290 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
3291 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3292
3293 webrtc::VideoEncoderConfig encoder_config =
3294 send_stream->GetEncoderConfig().Copy();
3295
3296 // Verify screencast settings.
3297 encoder_config = send_stream->GetEncoderConfig().Copy();
3298 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
3299 encoder_config.content_type);
3300
3301 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
3302 ASSERT_EQ(1u, streams.size());
3303 ASSERT_EQ(2u, streams[0].num_temporal_layers);
3304 EXPECT_EQ(kConferenceScreencastTemporalBitrateBps,
3305 streams[0].target_bitrate_bps);
3306
3307 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
3308 }
3309
TEST_F(WebRtcVideoChannelTest,SuspendBelowMinBitrateDisabledByDefault)3310 TEST_F(WebRtcVideoChannelTest, SuspendBelowMinBitrateDisabledByDefault) {
3311 FakeVideoSendStream* stream = AddSendStream();
3312 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
3313 }
3314
TEST_F(WebRtcVideoChannelTest,SetMediaConfigSuspendBelowMinBitrate)3315 TEST_F(WebRtcVideoChannelTest, SetMediaConfigSuspendBelowMinBitrate) {
3316 MediaConfig media_config = GetMediaConfig();
3317 media_config.video.suspend_below_min_bitrate = true;
3318
3319 channel_.reset(engine_.CreateMediaChannel(
3320 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3321 video_bitrate_allocator_factory_.get()));
3322 channel_->OnReadyToSend(true);
3323
3324 channel_->SetSendParameters(send_parameters_);
3325
3326 FakeVideoSendStream* stream = AddSendStream();
3327 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
3328
3329 media_config.video.suspend_below_min_bitrate = false;
3330 channel_.reset(engine_.CreateMediaChannel(
3331 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3332 video_bitrate_allocator_factory_.get()));
3333 channel_->OnReadyToSend(true);
3334
3335 channel_->SetSendParameters(send_parameters_);
3336
3337 stream = AddSendStream();
3338 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
3339 }
3340
TEST_F(WebRtcVideoChannelTest,Vp8DenoisingEnabledByDefault)3341 TEST_F(WebRtcVideoChannelTest, Vp8DenoisingEnabledByDefault) {
3342 FakeVideoSendStream* stream = AddSendStream();
3343 webrtc::VideoCodecVP8 vp8_settings;
3344 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3345 EXPECT_TRUE(vp8_settings.denoisingOn);
3346 }
3347
TEST_F(WebRtcVideoChannelTest,VerifyVp8SpecificSettings)3348 TEST_F(WebRtcVideoChannelTest, VerifyVp8SpecificSettings) {
3349 cricket::VideoSendParameters parameters;
3350 parameters.codecs.push_back(GetEngineCodec("VP8"));
3351 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3352
3353 // Single-stream settings should apply with RTX as well (verifies that we
3354 // check number of regular SSRCs and not StreamParams::ssrcs which contains
3355 // both RTX and regular SSRCs).
3356 FakeVideoSendStream* stream = SetUpSimulcast(false, true);
3357
3358 webrtc::test::FrameForwarder frame_forwarder;
3359 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
3360 channel_->SetSend(true);
3361
3362 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
3363
3364 webrtc::VideoCodecVP8 vp8_settings;
3365 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3366 EXPECT_TRUE(vp8_settings.denoisingOn)
3367 << "VP8 denoising should be on by default.";
3368
3369 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
3370
3371 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3372 EXPECT_FALSE(vp8_settings.denoisingOn);
3373 EXPECT_TRUE(vp8_settings.automaticResizeOn);
3374 EXPECT_TRUE(vp8_settings.frameDroppingOn);
3375
3376 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
3377
3378 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3379 EXPECT_TRUE(vp8_settings.denoisingOn);
3380 EXPECT_TRUE(vp8_settings.automaticResizeOn);
3381 EXPECT_TRUE(vp8_settings.frameDroppingOn);
3382
3383 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
3384 stream = SetUpSimulcast(true, false);
3385 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
3386 channel_->SetSend(true);
3387 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
3388
3389 EXPECT_EQ(3u, stream->GetVideoStreams().size());
3390 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3391 // Autmatic resize off when using simulcast.
3392 EXPECT_FALSE(vp8_settings.automaticResizeOn);
3393 EXPECT_TRUE(vp8_settings.frameDroppingOn);
3394
3395 // In screen-share mode, denoising is forced off.
3396 VideoOptions options;
3397 options.is_screencast = true;
3398 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3399
3400 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
3401
3402 EXPECT_EQ(3u, stream->GetVideoStreams().size());
3403 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3404 EXPECT_FALSE(vp8_settings.denoisingOn);
3405 // Resizing and frame dropping always off for screen sharing.
3406 EXPECT_FALSE(vp8_settings.automaticResizeOn);
3407 EXPECT_FALSE(vp8_settings.frameDroppingOn);
3408
3409 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
3410
3411 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3412 EXPECT_FALSE(vp8_settings.denoisingOn);
3413 EXPECT_FALSE(vp8_settings.automaticResizeOn);
3414 EXPECT_FALSE(vp8_settings.frameDroppingOn);
3415
3416 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
3417 }
3418
3419 // Test that setting the same options doesn't result in the encoder being
3420 // reconfigured.
TEST_F(WebRtcVideoChannelTest,SetIdenticalOptionsDoesntReconfigureEncoder)3421 TEST_F(WebRtcVideoChannelTest, SetIdenticalOptionsDoesntReconfigureEncoder) {
3422 VideoOptions options;
3423 webrtc::test::FrameForwarder frame_forwarder;
3424
3425 AddSendStream();
3426 cricket::VideoSendParameters parameters;
3427 parameters.codecs.push_back(GetEngineCodec("VP8"));
3428 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3429 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3430
3431 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3432 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3433 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
3434 // Expect 1 reconfigurations at this point from the initial configuration.
3435 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
3436
3437 // Set the options one more time and expect no additional reconfigurations.
3438 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3439 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
3440
3441 // Change |options| and expect 2 reconfigurations.
3442 options.video_noise_reduction = true;
3443 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3444 EXPECT_EQ(2, send_stream->num_encoder_reconfigurations());
3445
3446 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
3447 }
3448
3449 class Vp9SettingsTest : public WebRtcVideoChannelTest {
3450 public:
Vp9SettingsTest()3451 Vp9SettingsTest() : Vp9SettingsTest("") {}
Vp9SettingsTest(const char * field_trials)3452 explicit Vp9SettingsTest(const char* field_trials)
3453 : WebRtcVideoChannelTest(field_trials) {
3454 encoder_factory_->AddSupportedVideoCodecType("VP9");
3455 }
~Vp9SettingsTest()3456 virtual ~Vp9SettingsTest() {}
3457
3458 protected:
TearDown()3459 void TearDown() override {
3460 // Remove references to encoder_factory_ since this will be destroyed
3461 // before channel_ and engine_.
3462 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
3463 }
3464 };
3465
TEST_F(Vp9SettingsTest,VerifyVp9SpecificSettings)3466 TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
3467 cricket::VideoSendParameters parameters;
3468 parameters.codecs.push_back(GetEngineCodec("VP9"));
3469 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3470
3471 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
3472
3473 webrtc::test::FrameForwarder frame_forwarder;
3474 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
3475 channel_->SetSend(true);
3476
3477 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
3478
3479 webrtc::VideoCodecVP9 vp9_settings;
3480 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3481 EXPECT_TRUE(vp9_settings.denoisingOn)
3482 << "VP9 denoising should be on by default.";
3483
3484 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
3485
3486 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3487 EXPECT_FALSE(vp9_settings.denoisingOn);
3488 // Frame dropping always on for real time video.
3489 EXPECT_TRUE(vp9_settings.frameDroppingOn);
3490
3491 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
3492
3493 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3494 EXPECT_TRUE(vp9_settings.denoisingOn);
3495 EXPECT_TRUE(vp9_settings.frameDroppingOn);
3496
3497 // In screen-share mode, denoising is forced off.
3498 VideoOptions options;
3499 options.is_screencast = true;
3500 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3501
3502 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
3503
3504 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3505 EXPECT_FALSE(vp9_settings.denoisingOn);
3506 // Frame dropping always on for screen sharing.
3507 EXPECT_TRUE(vp9_settings.frameDroppingOn);
3508
3509 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
3510
3511 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3512 EXPECT_FALSE(vp9_settings.denoisingOn);
3513 EXPECT_TRUE(vp9_settings.frameDroppingOn);
3514
3515 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
3516 }
3517
TEST_F(Vp9SettingsTest,MultipleSsrcsEnablesSvc)3518 TEST_F(Vp9SettingsTest, MultipleSsrcsEnablesSvc) {
3519 cricket::VideoSendParameters parameters;
3520 parameters.codecs.push_back(GetEngineCodec("VP9"));
3521 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3522
3523 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3524
3525 FakeVideoSendStream* stream =
3526 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3527
3528 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3529
3530 webrtc::test::FrameForwarder frame_forwarder;
3531 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
3532 channel_->SetSend(true);
3533
3534 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
3535
3536 webrtc::VideoCodecVP9 vp9_settings;
3537 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3538
3539 const size_t kNumSpatialLayers = ssrcs.size();
3540 const size_t kNumTemporalLayers = 3;
3541 EXPECT_EQ(vp9_settings.numberOfSpatialLayers, kNumSpatialLayers);
3542 EXPECT_EQ(vp9_settings.numberOfTemporalLayers, kNumTemporalLayers);
3543
3544 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr));
3545 }
3546
TEST_F(Vp9SettingsTest,SvcModeCreatesSingleRtpStream)3547 TEST_F(Vp9SettingsTest, SvcModeCreatesSingleRtpStream) {
3548 cricket::VideoSendParameters parameters;
3549 parameters.codecs.push_back(GetEngineCodec("VP9"));
3550 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3551
3552 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3553
3554 FakeVideoSendStream* stream =
3555 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3556
3557 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3558
3559 // Despite 3 ssrcs provided, single layer is used.
3560 EXPECT_EQ(1u, config.rtp.ssrcs.size());
3561
3562 webrtc::test::FrameForwarder frame_forwarder;
3563 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
3564 channel_->SetSend(true);
3565
3566 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
3567
3568 webrtc::VideoCodecVP9 vp9_settings;
3569 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3570
3571 const size_t kNumSpatialLayers = ssrcs.size();
3572 EXPECT_EQ(vp9_settings.numberOfSpatialLayers, kNumSpatialLayers);
3573
3574 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr));
3575 }
3576
TEST_F(Vp9SettingsTest,AllEncodingParametersCopied)3577 TEST_F(Vp9SettingsTest, AllEncodingParametersCopied) {
3578 cricket::VideoSendParameters send_parameters;
3579 send_parameters.codecs.push_back(GetEngineCodec("VP9"));
3580 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
3581
3582 const size_t kNumSpatialLayers = 3;
3583 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3584
3585 FakeVideoSendStream* stream =
3586 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3587
3588 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrcs[0]);
3589 ASSERT_EQ(kNumSpatialLayers, parameters.encodings.size());
3590 ASSERT_TRUE(parameters.encodings[0].active);
3591 ASSERT_TRUE(parameters.encodings[1].active);
3592 ASSERT_TRUE(parameters.encodings[2].active);
3593 // Invert value to verify copying.
3594 parameters.encodings[1].active = false;
3595 EXPECT_TRUE(channel_->SetRtpSendParameters(ssrcs[0], parameters).ok());
3596
3597 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
3598
3599 // number_of_streams should be 1 since all spatial layers are sent on the
3600 // same SSRC. But encoding parameters of all layers is supposed to be copied
3601 // and stored in simulcast_layers[].
3602 EXPECT_EQ(1u, encoder_config.number_of_streams);
3603 EXPECT_EQ(encoder_config.simulcast_layers.size(), kNumSpatialLayers);
3604 EXPECT_TRUE(encoder_config.simulcast_layers[0].active);
3605 EXPECT_FALSE(encoder_config.simulcast_layers[1].active);
3606 EXPECT_TRUE(encoder_config.simulcast_layers[2].active);
3607 }
3608
3609 class Vp9SettingsTestWithFieldTrial
3610 : public Vp9SettingsTest,
3611 public ::testing::WithParamInterface<
3612 ::testing::tuple<const char*, int, int, webrtc::InterLayerPredMode>> {
3613 protected:
Vp9SettingsTestWithFieldTrial()3614 Vp9SettingsTestWithFieldTrial()
3615 : Vp9SettingsTest(::testing::get<0>(GetParam())),
3616 num_spatial_layers_(::testing::get<1>(GetParam())),
3617 num_temporal_layers_(::testing::get<2>(GetParam())),
3618 inter_layer_pred_mode_(::testing::get<3>(GetParam())) {}
3619
VerifySettings(int num_spatial_layers,int num_temporal_layers,webrtc::InterLayerPredMode interLayerPred)3620 void VerifySettings(int num_spatial_layers,
3621 int num_temporal_layers,
3622 webrtc::InterLayerPredMode interLayerPred) {
3623 cricket::VideoSendParameters parameters;
3624 parameters.codecs.push_back(GetEngineCodec("VP9"));
3625 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3626
3627 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
3628
3629 webrtc::test::FrameForwarder frame_forwarder;
3630 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
3631 channel_->SetSend(true);
3632
3633 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
3634
3635 webrtc::VideoCodecVP9 vp9_settings;
3636 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3637 EXPECT_EQ(num_spatial_layers, vp9_settings.numberOfSpatialLayers);
3638 EXPECT_EQ(num_temporal_layers, vp9_settings.numberOfTemporalLayers);
3639 EXPECT_EQ(inter_layer_pred_mode_, vp9_settings.interLayerPred);
3640
3641 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
3642 }
3643
3644 const uint8_t num_spatial_layers_;
3645 const uint8_t num_temporal_layers_;
3646 const webrtc::InterLayerPredMode inter_layer_pred_mode_;
3647 };
3648
TEST_P(Vp9SettingsTestWithFieldTrial,VerifyCodecSettings)3649 TEST_P(Vp9SettingsTestWithFieldTrial, VerifyCodecSettings) {
3650 VerifySettings(num_spatial_layers_, num_temporal_layers_,
3651 inter_layer_pred_mode_);
3652 }
3653
3654 INSTANTIATE_TEST_SUITE_P(
3655 All,
3656 Vp9SettingsTestWithFieldTrial,
3657 Values(
3658 std::make_tuple("", 1, 1, webrtc::InterLayerPredMode::kOnKeyPic),
3659 std::make_tuple("WebRTC-SupportVP9SVC/Default/",
3660 1,
3661 1,
3662 webrtc::InterLayerPredMode::kOnKeyPic),
3663 std::make_tuple("WebRTC-SupportVP9SVC/EnabledByFlag_2SL3TL/",
3664 2,
3665 3,
3666 webrtc::InterLayerPredMode::kOnKeyPic),
3667 std::make_tuple("WebRTC-Vp9InterLayerPred/Default/",
3668 1,
3669 1,
3670 webrtc::InterLayerPredMode::kOnKeyPic),
3671 std::make_tuple("WebRTC-Vp9InterLayerPred/Disabled/",
3672 1,
3673 1,
3674 webrtc::InterLayerPredMode::kOnKeyPic),
3675 std::make_tuple(
3676 "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:off/",
3677 1,
3678 1,
3679 webrtc::InterLayerPredMode::kOff),
3680 std::make_tuple(
3681 "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:on/",
3682 1,
3683 1,
3684 webrtc::InterLayerPredMode::kOn),
3685 std::make_tuple(
3686 "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:onkeypic/",
3687 1,
3688 1,
3689 webrtc::InterLayerPredMode::kOnKeyPic)));
3690
TEST_F(WebRtcVideoChannelTest,VerifyMinBitrate)3691 TEST_F(WebRtcVideoChannelTest, VerifyMinBitrate) {
3692 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3693 ASSERT_EQ(1u, streams.size());
3694 EXPECT_EQ(webrtc::kDefaultMinVideoBitrateBps, streams[0].min_bitrate_bps);
3695 }
3696
TEST_F(WebRtcVideoChannelTest,VerifyMinBitrateWithForcedFallbackFieldTrial)3697 TEST_F(WebRtcVideoChannelTest, VerifyMinBitrateWithForcedFallbackFieldTrial) {
3698 RTC_DCHECK(!override_field_trials_);
3699 override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>(
3700 "WebRTC-VP8-Forced-Fallback-Encoder-v2/Enabled-1,2,34567/");
3701 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3702 ASSERT_EQ(1u, streams.size());
3703 EXPECT_EQ(34567, streams[0].min_bitrate_bps);
3704 }
3705
TEST_F(WebRtcVideoChannelTest,BalancedDegradationPreferenceNotSupportedWithoutFieldtrial)3706 TEST_F(WebRtcVideoChannelTest,
3707 BalancedDegradationPreferenceNotSupportedWithoutFieldtrial) {
3708 RTC_DCHECK(!override_field_trials_);
3709 override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>(
3710 "WebRTC-Video-BalancedDegradation/Disabled/");
3711 const bool kResolutionScalingEnabled = true;
3712 const bool kFpsScalingEnabled = false;
3713 TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
3714 }
3715
TEST_F(WebRtcVideoChannelTest,BalancedDegradationPreferenceSupportedBehindFieldtrial)3716 TEST_F(WebRtcVideoChannelTest,
3717 BalancedDegradationPreferenceSupportedBehindFieldtrial) {
3718 RTC_DCHECK(!override_field_trials_);
3719 override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>(
3720 "WebRTC-Video-BalancedDegradation/Enabled/");
3721 const bool kResolutionScalingEnabled = true;
3722 const bool kFpsScalingEnabled = true;
3723 TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
3724 }
3725
TEST_F(WebRtcVideoChannelTest,AdaptsOnOveruse)3726 TEST_F(WebRtcVideoChannelTest, AdaptsOnOveruse) {
3727 TestCpuAdaptation(true, false);
3728 }
3729
TEST_F(WebRtcVideoChannelTest,DoesNotAdaptOnOveruseWhenDisabled)3730 TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenDisabled) {
3731 TestCpuAdaptation(false, false);
3732 }
3733
TEST_F(WebRtcVideoChannelTest,DoesNotAdaptWhenScreeensharing)3734 TEST_F(WebRtcVideoChannelTest, DoesNotAdaptWhenScreeensharing) {
3735 TestCpuAdaptation(false, true);
3736 }
3737
TEST_F(WebRtcVideoChannelTest,DoesNotAdaptOnOveruseWhenScreensharing)3738 TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenScreensharing) {
3739 TestCpuAdaptation(true, true);
3740 }
3741
TEST_F(WebRtcVideoChannelTest,PreviousAdaptationDoesNotApplyToScreenshare)3742 TEST_F(WebRtcVideoChannelTest, PreviousAdaptationDoesNotApplyToScreenshare) {
3743 cricket::VideoCodec codec = GetEngineCodec("VP8");
3744 cricket::VideoSendParameters parameters;
3745 parameters.codecs.push_back(codec);
3746
3747 MediaConfig media_config = GetMediaConfig();
3748 media_config.video.enable_cpu_adaptation = true;
3749 channel_.reset(engine_.CreateMediaChannel(
3750 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3751 video_bitrate_allocator_factory_.get()));
3752 channel_->OnReadyToSend(true);
3753 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3754
3755 AddSendStream();
3756 webrtc::test::FrameForwarder frame_forwarder;
3757
3758 ASSERT_TRUE(channel_->SetSend(true));
3759 cricket::VideoOptions camera_options;
3760 camera_options.is_screencast = false;
3761 channel_->SetVideoSend(last_ssrc_, &camera_options, &frame_forwarder);
3762
3763 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
3764 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3765
3766 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
3767 // Dont' expect anything on framerate_scaling_enabled, since the default is
3768 // transitioning from MAINTAIN_FRAMERATE to BALANCED.
3769
3770 // Switch to screen share. Expect no resolution scaling.
3771 cricket::VideoOptions screenshare_options;
3772 screenshare_options.is_screencast = true;
3773 channel_->SetVideoSend(last_ssrc_, &screenshare_options, &frame_forwarder);
3774 ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
3775 send_stream = fake_call_->GetVideoSendStreams().front();
3776 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
3777
3778 // Switch back to the normal capturer. Expect resolution scaling to be
3779 // reenabled.
3780 channel_->SetVideoSend(last_ssrc_, &camera_options, &frame_forwarder);
3781 send_stream = fake_call_->GetVideoSendStreams().front();
3782 ASSERT_EQ(3, fake_call_->GetNumCreatedSendStreams());
3783 send_stream = fake_call_->GetVideoSendStreams().front();
3784 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
3785
3786 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
3787 }
3788
3789 // TODO(asapersson): Remove this test when the balanced field trial is removed.
TestDegradationPreference(bool resolution_scaling_enabled,bool fps_scaling_enabled)3790 void WebRtcVideoChannelTest::TestDegradationPreference(
3791 bool resolution_scaling_enabled,
3792 bool fps_scaling_enabled) {
3793 cricket::VideoCodec codec = GetEngineCodec("VP8");
3794 cricket::VideoSendParameters parameters;
3795 parameters.codecs.push_back(codec);
3796
3797 MediaConfig media_config = GetMediaConfig();
3798 media_config.video.enable_cpu_adaptation = true;
3799 channel_.reset(engine_.CreateMediaChannel(
3800 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3801 video_bitrate_allocator_factory_.get()));
3802 channel_->OnReadyToSend(true);
3803
3804 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3805
3806 AddSendStream();
3807
3808 webrtc::test::FrameForwarder frame_forwarder;
3809 VideoOptions options;
3810 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3811
3812 EXPECT_TRUE(channel_->SetSend(true));
3813
3814 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3815 EXPECT_EQ(resolution_scaling_enabled,
3816 send_stream->resolution_scaling_enabled());
3817 EXPECT_EQ(fps_scaling_enabled, send_stream->framerate_scaling_enabled());
3818
3819 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
3820 }
3821
TestCpuAdaptation(bool enable_overuse,bool is_screenshare)3822 void WebRtcVideoChannelTest::TestCpuAdaptation(bool enable_overuse,
3823 bool is_screenshare) {
3824 cricket::VideoCodec codec = GetEngineCodec("VP8");
3825 cricket::VideoSendParameters parameters;
3826 parameters.codecs.push_back(codec);
3827
3828 MediaConfig media_config = GetMediaConfig();
3829 if (enable_overuse) {
3830 media_config.video.enable_cpu_adaptation = true;
3831 }
3832 channel_.reset(engine_.CreateMediaChannel(
3833 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3834 video_bitrate_allocator_factory_.get()));
3835 channel_->OnReadyToSend(true);
3836
3837 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3838
3839 AddSendStream();
3840
3841 webrtc::test::FrameForwarder frame_forwarder;
3842 VideoOptions options;
3843 options.is_screencast = is_screenshare;
3844 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3845
3846 EXPECT_TRUE(channel_->SetSend(true));
3847
3848 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3849
3850 if (!enable_overuse) {
3851 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
3852 EXPECT_FALSE(send_stream->framerate_scaling_enabled());
3853 } else if (is_screenshare) {
3854 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
3855 EXPECT_TRUE(send_stream->framerate_scaling_enabled());
3856 } else {
3857 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
3858 EXPECT_FALSE(send_stream->framerate_scaling_enabled());
3859 }
3860 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
3861 }
3862
TEST_F(WebRtcVideoChannelTest,EstimatesNtpStartTimeCorrectly)3863 TEST_F(WebRtcVideoChannelTest, EstimatesNtpStartTimeCorrectly) {
3864 // Start at last timestamp to verify that wraparounds are estimated correctly.
3865 static const uint32_t kInitialTimestamp = 0xFFFFFFFFu;
3866 static const int64_t kInitialNtpTimeMs = 1247891230;
3867 static const int kFrameOffsetMs = 20;
3868 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
3869
3870 FakeVideoReceiveStream* stream = AddRecvStream();
3871 cricket::FakeVideoRenderer renderer;
3872 EXPECT_TRUE(channel_->SetSink(last_ssrc_, &renderer));
3873
3874 webrtc::VideoFrame video_frame =
3875 webrtc::VideoFrame::Builder()
3876 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
3877 .set_timestamp_rtp(kInitialTimestamp)
3878 .set_timestamp_us(0)
3879 .set_rotation(webrtc::kVideoRotation_0)
3880 .build();
3881 // Initial NTP time is not available on the first frame, but should still be
3882 // able to be estimated.
3883 stream->InjectFrame(video_frame);
3884
3885 EXPECT_EQ(1, renderer.num_rendered_frames());
3886
3887 // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which
3888 // triggers a constant-overflow warning, hence we're calculating it explicitly
3889 // here.
3890 fake_clock_.AdvanceTime(webrtc::TimeDelta::Millis(kFrameOffsetMs));
3891 video_frame.set_timestamp(kFrameOffsetMs * 90 - 1);
3892 video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs);
3893 stream->InjectFrame(video_frame);
3894
3895 EXPECT_EQ(2, renderer.num_rendered_frames());
3896
3897 // Verify that NTP time has been correctly deduced.
3898 cricket::VideoMediaInfo info;
3899 ASSERT_TRUE(channel_->GetStats(&info));
3900 ASSERT_EQ(1u, info.receivers.size());
3901 EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms);
3902 }
3903
TEST_F(WebRtcVideoChannelTest,SetDefaultSendCodecs)3904 TEST_F(WebRtcVideoChannelTest, SetDefaultSendCodecs) {
3905 AssignDefaultAptRtxTypes();
3906 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
3907
3908 VideoCodec codec;
3909 EXPECT_TRUE(channel_->GetSendCodec(&codec));
3910 EXPECT_TRUE(codec.Matches(engine_.send_codecs()[0]));
3911
3912 // Using a RTX setup to verify that the default RTX payload type is good.
3913 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3914 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
3915 FakeVideoSendStream* stream = AddSendStream(
3916 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
3917 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3918
3919 // Make sure NACK and FEC are enabled on the correct payload types.
3920 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
3921 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
3922 EXPECT_EQ(GetEngineCodec("red").id, config.rtp.ulpfec.red_payload_type);
3923
3924 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
3925 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
3926 VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_);
3927 // TODO(juberti): Check RTCP, PLI, TMMBR.
3928 }
3929
TEST_F(WebRtcVideoChannelTest,SetSendCodecsWithoutPacketization)3930 TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutPacketization) {
3931 cricket::VideoSendParameters parameters;
3932 parameters.codecs.push_back(GetEngineCodec("VP8"));
3933 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3934
3935 FakeVideoSendStream* stream = AddSendStream();
3936 const webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3937 EXPECT_FALSE(config.rtp.raw_payload);
3938 }
3939
TEST_F(WebRtcVideoChannelTest,SetSendCodecsWithPacketization)3940 TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithPacketization) {
3941 cricket::VideoSendParameters parameters;
3942 parameters.codecs.push_back(GetEngineCodec("VP8"));
3943 parameters.codecs.back().packetization = kPacketizationParamRaw;
3944 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3945
3946 FakeVideoSendStream* stream = AddSendStream();
3947 const webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3948 EXPECT_TRUE(config.rtp.raw_payload);
3949 }
3950
3951 // The following four tests ensures that FlexFEC is not activated by default
3952 // when the field trials are not enabled.
3953 // TODO(brandtr): Remove or update these tests when FlexFEC _is_ enabled by
3954 // default.
TEST_F(WebRtcVideoChannelTest,FlexfecSendCodecWithoutSsrcNotExposedByDefault)3955 TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithoutSsrcNotExposedByDefault) {
3956 FakeVideoSendStream* stream = AddSendStream();
3957 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3958
3959 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
3960 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3961 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3962 }
3963
TEST_F(WebRtcVideoChannelTest,FlexfecSendCodecWithSsrcNotExposedByDefault)3964 TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithSsrcNotExposedByDefault) {
3965 FakeVideoSendStream* stream = AddSendStream(
3966 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3967 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3968
3969 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
3970 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3971 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3972 }
3973
TEST_F(WebRtcVideoChannelTest,FlexfecRecvCodecWithoutSsrcNotExposedByDefault)3974 TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithoutSsrcNotExposedByDefault) {
3975 AddRecvStream();
3976
3977 const std::vector<FakeFlexfecReceiveStream*>& streams =
3978 fake_call_->GetFlexfecReceiveStreams();
3979 EXPECT_TRUE(streams.empty());
3980 }
3981
TEST_F(WebRtcVideoChannelTest,FlexfecRecvCodecWithSsrcNotExposedByDefault)3982 TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithSsrcNotExposedByDefault) {
3983 AddRecvStream(
3984 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3985
3986 const std::vector<FakeFlexfecReceiveStream*>& streams =
3987 fake_call_->GetFlexfecReceiveStreams();
3988 EXPECT_TRUE(streams.empty());
3989 }
3990
3991 // TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
3992 // tests that use this test fixture into the corresponding "non-field trial"
3993 // tests.
3994 class WebRtcVideoChannelFlexfecRecvTest : public WebRtcVideoChannelTest {
3995 public:
WebRtcVideoChannelFlexfecRecvTest()3996 WebRtcVideoChannelFlexfecRecvTest()
3997 : WebRtcVideoChannelTest("WebRTC-FlexFEC-03-Advertised/Enabled/") {}
3998 };
3999
TEST_F(WebRtcVideoChannelFlexfecRecvTest,DefaultFlexfecCodecHasTransportCcAndRembFeedbackParam)4000 TEST_F(WebRtcVideoChannelFlexfecRecvTest,
4001 DefaultFlexfecCodecHasTransportCcAndRembFeedbackParam) {
4002 EXPECT_TRUE(cricket::HasTransportCc(GetEngineCodec("flexfec-03")));
4003 EXPECT_TRUE(cricket::HasRemb(GetEngineCodec("flexfec-03")));
4004 }
4005
TEST_F(WebRtcVideoChannelFlexfecRecvTest,SetDefaultRecvCodecsWithoutSsrc)4006 TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithoutSsrc) {
4007 AddRecvStream();
4008
4009 const std::vector<FakeFlexfecReceiveStream*>& streams =
4010 fake_call_->GetFlexfecReceiveStreams();
4011 EXPECT_TRUE(streams.empty());
4012
4013 const std::vector<FakeVideoReceiveStream*>& video_streams =
4014 fake_call_->GetVideoReceiveStreams();
4015 ASSERT_EQ(1U, video_streams.size());
4016 const FakeVideoReceiveStream& video_stream = *video_streams.front();
4017 EXPECT_EQ(0, video_stream.GetNumAddedSecondarySinks());
4018 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
4019 }
4020
TEST_F(WebRtcVideoChannelFlexfecRecvTest,SetDefaultRecvCodecsWithSsrc)4021 TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithSsrc) {
4022 AddRecvStream(
4023 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4024
4025 const std::vector<FakeFlexfecReceiveStream*>& streams =
4026 fake_call_->GetFlexfecReceiveStreams();
4027 ASSERT_EQ(1U, streams.size());
4028 const FakeFlexfecReceiveStream* stream = streams.front();
4029 const webrtc::FlexfecReceiveStream::Config& config = stream->GetConfig();
4030 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.payload_type);
4031 EXPECT_EQ(kFlexfecSsrc, config.remote_ssrc);
4032 ASSERT_EQ(1U, config.protected_media_ssrcs.size());
4033 EXPECT_EQ(kSsrcs1[0], config.protected_media_ssrcs[0]);
4034
4035 const std::vector<FakeVideoReceiveStream*>& video_streams =
4036 fake_call_->GetVideoReceiveStreams();
4037 ASSERT_EQ(1U, video_streams.size());
4038 const FakeVideoReceiveStream& video_stream = *video_streams.front();
4039 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
4040 const webrtc::VideoReceiveStream::Config& video_config =
4041 video_stream.GetConfig();
4042 EXPECT_TRUE(video_config.rtp.protected_by_flexfec);
4043 }
4044
TEST_F(WebRtcVideoChannelFlexfecRecvTest,EnablingFlexfecDoesNotRecreateVideoReceiveStream)4045 TEST_F(WebRtcVideoChannelFlexfecRecvTest,
4046 EnablingFlexfecDoesNotRecreateVideoReceiveStream) {
4047 cricket::VideoRecvParameters recv_parameters;
4048 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4049 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4050
4051 AddRecvStream(
4052 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4053 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
4054 const std::vector<FakeVideoReceiveStream*>& video_streams =
4055 fake_call_->GetVideoReceiveStreams();
4056 ASSERT_EQ(1U, video_streams.size());
4057 const FakeVideoReceiveStream& video_stream = *video_streams.front();
4058 EXPECT_EQ(0, video_stream.GetNumAddedSecondarySinks());
4059 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
4060
4061 // Enable FlexFEC.
4062 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4063 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4064 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams())
4065 << "Enabling FlexFEC should create FlexfecReceiveStream.";
4066 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
4067 << "Enabling FlexFEC should not create VideoReceiveStream.";
4068 EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size())
4069 << "Enabling FlexFEC should create a single FlexfecReceiveStream.";
4070 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
4071 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
4072 }
4073
TEST_F(WebRtcVideoChannelFlexfecRecvTest,DisablingFlexfecDoesNotRecreateVideoReceiveStream)4074 TEST_F(WebRtcVideoChannelFlexfecRecvTest,
4075 DisablingFlexfecDoesNotRecreateVideoReceiveStream) {
4076 cricket::VideoRecvParameters recv_parameters;
4077 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4078 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4079 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4080
4081 AddRecvStream(
4082 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4083 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
4084 EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size());
4085 const std::vector<FakeVideoReceiveStream*>& video_streams =
4086 fake_call_->GetVideoReceiveStreams();
4087 ASSERT_EQ(1U, video_streams.size());
4088 const FakeVideoReceiveStream& video_stream = *video_streams.front();
4089 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
4090 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
4091
4092 // Disable FlexFEC.
4093 recv_parameters.codecs.clear();
4094 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4095 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4096 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams())
4097 << "Disabling FlexFEC should not recreate VideoReceiveStream.";
4098 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
4099 << "Disabling FlexFEC should not destroy VideoReceiveStream.";
4100 EXPECT_TRUE(fake_call_->GetFlexfecReceiveStreams().empty())
4101 << "Disabling FlexFEC should destroy FlexfecReceiveStream.";
4102 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
4103 EXPECT_EQ(1, video_stream.GetNumRemovedSecondarySinks());
4104 }
4105
TEST_F(WebRtcVideoChannelFlexfecRecvTest,DuplicateFlexfecCodecIsDropped)4106 TEST_F(WebRtcVideoChannelFlexfecRecvTest, DuplicateFlexfecCodecIsDropped) {
4107 constexpr int kUnusedPayloadType1 = 127;
4108
4109 cricket::VideoRecvParameters recv_parameters;
4110 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4111 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4112 cricket::VideoCodec duplicate = GetEngineCodec("flexfec-03");
4113 duplicate.id = kUnusedPayloadType1;
4114 recv_parameters.codecs.push_back(duplicate);
4115 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4116
4117 AddRecvStream(
4118 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4119
4120 const std::vector<FakeFlexfecReceiveStream*>& streams =
4121 fake_call_->GetFlexfecReceiveStreams();
4122 ASSERT_EQ(1U, streams.size());
4123 const FakeFlexfecReceiveStream* stream = streams.front();
4124 const webrtc::FlexfecReceiveStream::Config& config = stream->GetConfig();
4125 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.payload_type);
4126 }
4127
4128 // TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
4129 // tests that use this test fixture into the corresponding "non-field trial"
4130 // tests.
4131 class WebRtcVideoChannelFlexfecSendRecvTest : public WebRtcVideoChannelTest {
4132 public:
WebRtcVideoChannelFlexfecSendRecvTest()4133 WebRtcVideoChannelFlexfecSendRecvTest()
4134 : WebRtcVideoChannelTest(
4135 "WebRTC-FlexFEC-03-Advertised/Enabled/WebRTC-FlexFEC-03/Enabled/") {
4136 }
4137 };
4138
TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,SetDefaultSendCodecsWithoutSsrc)4139 TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithoutSsrc) {
4140 FakeVideoSendStream* stream = AddSendStream();
4141 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
4142
4143 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
4144 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
4145 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
4146 }
4147
TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,SetDefaultSendCodecsWithSsrc)4148 TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithSsrc) {
4149 FakeVideoSendStream* stream = AddSendStream(
4150 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4151 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
4152
4153 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
4154 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
4155 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
4156 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
4157 }
4158
TEST_F(WebRtcVideoChannelTest,SetSendCodecsWithoutFec)4159 TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFec) {
4160 cricket::VideoSendParameters parameters;
4161 parameters.codecs.push_back(GetEngineCodec("VP8"));
4162 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4163
4164 FakeVideoSendStream* stream = AddSendStream();
4165 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
4166
4167 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type);
4168 EXPECT_EQ(-1, config.rtp.ulpfec.red_payload_type);
4169 }
4170
TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,SetSendCodecsWithoutFec)4171 TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetSendCodecsWithoutFec) {
4172 cricket::VideoSendParameters parameters;
4173 parameters.codecs.push_back(GetEngineCodec("VP8"));
4174 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4175
4176 FakeVideoSendStream* stream = AddSendStream();
4177 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
4178
4179 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
4180 }
4181
TEST_F(WebRtcVideoChannelFlexfecRecvTest,SetRecvCodecsWithFec)4182 TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvCodecsWithFec) {
4183 AddRecvStream(
4184 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4185
4186 cricket::VideoRecvParameters recv_parameters;
4187 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4188 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4189 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4190
4191 const std::vector<FakeFlexfecReceiveStream*>& flexfec_streams =
4192 fake_call_->GetFlexfecReceiveStreams();
4193 ASSERT_EQ(1U, flexfec_streams.size());
4194 const FakeFlexfecReceiveStream* flexfec_stream = flexfec_streams.front();
4195 const webrtc::FlexfecReceiveStream::Config& flexfec_stream_config =
4196 flexfec_stream->GetConfig();
4197 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
4198 flexfec_stream_config.payload_type);
4199 EXPECT_EQ(kFlexfecSsrc, flexfec_stream_config.remote_ssrc);
4200 ASSERT_EQ(1U, flexfec_stream_config.protected_media_ssrcs.size());
4201 EXPECT_EQ(kSsrcs1[0], flexfec_stream_config.protected_media_ssrcs[0]);
4202 const std::vector<FakeVideoReceiveStream*>& video_streams =
4203 fake_call_->GetVideoReceiveStreams();
4204 const FakeVideoReceiveStream* video_stream = video_streams.front();
4205 const webrtc::VideoReceiveStream::Config& video_stream_config =
4206 video_stream->GetConfig();
4207 EXPECT_EQ(video_stream_config.rtp.local_ssrc,
4208 flexfec_stream_config.local_ssrc);
4209 EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
4210 EXPECT_EQ(video_stream_config.rtcp_send_transport,
4211 flexfec_stream_config.rtcp_send_transport);
4212 // TODO(brandtr): Update this EXPECT when we set |transport_cc| in a
4213 // spec-compliant way.
4214 EXPECT_EQ(video_stream_config.rtp.transport_cc,
4215 flexfec_stream_config.transport_cc);
4216 EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
4217 EXPECT_EQ(video_stream_config.rtp.extensions,
4218 flexfec_stream_config.rtp_header_extensions);
4219 }
4220
4221 // We should not send FlexFEC, even if we advertise it, unless the right
4222 // field trial is set.
4223 // TODO(brandtr): Remove when FlexFEC is enabled by default.
TEST_F(WebRtcVideoChannelFlexfecRecvTest,SetSendCodecsWithoutSsrcWithFecDoesNotEnableFec)4224 TEST_F(WebRtcVideoChannelFlexfecRecvTest,
4225 SetSendCodecsWithoutSsrcWithFecDoesNotEnableFec) {
4226 cricket::VideoSendParameters parameters;
4227 parameters.codecs.push_back(GetEngineCodec("VP8"));
4228 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4229 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4230
4231 FakeVideoSendStream* stream = AddSendStream();
4232 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
4233
4234 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
4235 EXPECT_EQ(0u, config.rtp.flexfec.ssrc);
4236 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
4237 }
4238
TEST_F(WebRtcVideoChannelFlexfecRecvTest,SetSendCodecsWithSsrcWithFecDoesNotEnableFec)4239 TEST_F(WebRtcVideoChannelFlexfecRecvTest,
4240 SetSendCodecsWithSsrcWithFecDoesNotEnableFec) {
4241 cricket::VideoSendParameters parameters;
4242 parameters.codecs.push_back(GetEngineCodec("VP8"));
4243 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4244 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4245
4246 FakeVideoSendStream* stream = AddSendStream(
4247 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4248 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
4249
4250 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
4251 EXPECT_EQ(0u, config.rtp.flexfec.ssrc);
4252 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
4253 }
4254
TEST_F(WebRtcVideoChannelTest,SetSendCodecRejectsRtxWithoutAssociatedPayloadType)4255 TEST_F(WebRtcVideoChannelTest,
4256 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
4257 const int kUnusedPayloadType = 127;
4258 EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType));
4259
4260 cricket::VideoSendParameters parameters;
4261 cricket::VideoCodec rtx_codec(kUnusedPayloadType, "rtx");
4262 parameters.codecs.push_back(rtx_codec);
4263 EXPECT_FALSE(channel_->SetSendParameters(parameters))
4264 << "RTX codec without associated payload type should be rejected.";
4265 }
4266
TEST_F(WebRtcVideoChannelTest,SetSendCodecRejectsRtxWithoutMatchingVideoCodec)4267 TEST_F(WebRtcVideoChannelTest,
4268 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
4269 const int kUnusedPayloadType1 = 126;
4270 const int kUnusedPayloadType2 = 127;
4271 EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType1));
4272 EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType2));
4273 {
4274 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
4275 kUnusedPayloadType1, GetEngineCodec("VP8").id);
4276 cricket::VideoSendParameters parameters;
4277 parameters.codecs.push_back(GetEngineCodec("VP8"));
4278 parameters.codecs.push_back(rtx_codec);
4279 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4280 }
4281 {
4282 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
4283 kUnusedPayloadType1, kUnusedPayloadType2);
4284 cricket::VideoSendParameters parameters;
4285 parameters.codecs.push_back(GetEngineCodec("VP8"));
4286 parameters.codecs.push_back(rtx_codec);
4287 EXPECT_FALSE(channel_->SetSendParameters(parameters))
4288 << "RTX without matching video codec should be rejected.";
4289 }
4290 }
4291
TEST_F(WebRtcVideoChannelTest,SetSendCodecsWithChangedRtxPayloadType)4292 TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithChangedRtxPayloadType) {
4293 const int kUnusedPayloadType1 = 126;
4294 const int kUnusedPayloadType2 = 127;
4295 EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType1));
4296 EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType2));
4297
4298 // SSRCs for RTX.
4299 cricket::StreamParams params =
4300 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
4301 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
4302 AddSendStream(params);
4303
4304 // Original payload type for RTX.
4305 cricket::VideoSendParameters parameters;
4306 parameters.codecs.push_back(GetEngineCodec("VP8"));
4307 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
4308 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
4309 parameters.codecs.push_back(rtx_codec);
4310 EXPECT_TRUE(channel_->SetSendParameters(parameters));
4311 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
4312 const webrtc::VideoSendStream::Config& config_before =
4313 fake_call_->GetVideoSendStreams()[0]->GetConfig();
4314 EXPECT_EQ(kUnusedPayloadType1, config_before.rtp.rtx.payload_type);
4315 ASSERT_EQ(1U, config_before.rtp.rtx.ssrcs.size());
4316 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx.ssrcs[0]);
4317
4318 // Change payload type for RTX.
4319 parameters.codecs[1].id = kUnusedPayloadType2;
4320 EXPECT_TRUE(channel_->SetSendParameters(parameters));
4321 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
4322 const webrtc::VideoSendStream::Config& config_after =
4323 fake_call_->GetVideoSendStreams()[0]->GetConfig();
4324 EXPECT_EQ(kUnusedPayloadType2, config_after.rtp.rtx.payload_type);
4325 ASSERT_EQ(1U, config_after.rtp.rtx.ssrcs.size());
4326 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx.ssrcs[0]);
4327 }
4328
TEST_F(WebRtcVideoChannelTest,SetSendCodecsWithoutFecDisablesFec)4329 TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFecDisablesFec) {
4330 cricket::VideoSendParameters parameters;
4331 parameters.codecs.push_back(GetEngineCodec("VP8"));
4332 parameters.codecs.push_back(GetEngineCodec("ulpfec"));
4333 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4334
4335 FakeVideoSendStream* stream = AddSendStream();
4336 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
4337
4338 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
4339
4340 parameters.codecs.pop_back();
4341 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4342 stream = fake_call_->GetVideoSendStreams()[0];
4343 ASSERT_TRUE(stream != nullptr);
4344 config = stream->GetConfig().Copy();
4345 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type)
4346 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
4347 }
4348
TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,SetSendCodecsWithoutFecDisablesFec)4349 TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
4350 SetSendCodecsWithoutFecDisablesFec) {
4351 cricket::VideoSendParameters parameters;
4352 parameters.codecs.push_back(GetEngineCodec("VP8"));
4353 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4354 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4355
4356 FakeVideoSendStream* stream = AddSendStream(
4357 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4358 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
4359
4360 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
4361 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
4362 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
4363 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
4364
4365 parameters.codecs.pop_back();
4366 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4367 stream = fake_call_->GetVideoSendStreams()[0];
4368 ASSERT_TRUE(stream != nullptr);
4369 config = stream->GetConfig().Copy();
4370 EXPECT_EQ(-1, config.rtp.flexfec.payload_type)
4371 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
4372 }
4373
TEST_F(WebRtcVideoChannelTest,SetSendCodecsChangesExistingStreams)4374 TEST_F(WebRtcVideoChannelTest, SetSendCodecsChangesExistingStreams) {
4375 cricket::VideoSendParameters parameters;
4376 cricket::VideoCodec codec(100, "VP8");
4377 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax);
4378 parameters.codecs.push_back(codec);
4379
4380 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4381 channel_->SetSend(true);
4382
4383 FakeVideoSendStream* stream = AddSendStream();
4384 webrtc::test::FrameForwarder frame_forwarder;
4385 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
4386
4387 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
4388 EXPECT_EQ(kDefaultQpMax, streams[0].max_qp);
4389
4390 parameters.codecs.clear();
4391 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax + 1);
4392 parameters.codecs.push_back(codec);
4393 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4394 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
4395 EXPECT_EQ(kDefaultQpMax + 1, streams[0].max_qp);
4396 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
4397 }
4398
TEST_F(WebRtcVideoChannelTest,SetSendCodecsWithBitrates)4399 TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitrates) {
4400 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
4401 200000);
4402 }
4403
TEST_F(WebRtcVideoChannelTest,SetSendCodecsWithHighMaxBitrate)4404 TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithHighMaxBitrate) {
4405 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
4406 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
4407 ASSERT_EQ(1u, streams.size());
4408 EXPECT_EQ(10000000, streams[0].max_bitrate_bps);
4409 }
4410
TEST_F(WebRtcVideoChannelTest,SetSendCodecsWithoutBitratesUsesCorrectDefaults)4411 TEST_F(WebRtcVideoChannelTest,
4412 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
4413 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
4414 }
4415
TEST_F(WebRtcVideoChannelTest,SetSendCodecsCapsMinAndStartBitrate)4416 TEST_F(WebRtcVideoChannelTest, SetSendCodecsCapsMinAndStartBitrate) {
4417 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
4418 }
4419
TEST_F(WebRtcVideoChannelTest,SetSendCodecsRejectsMaxLessThanMinBitrate)4420 TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectsMaxLessThanMinBitrate) {
4421 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "300";
4422 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "200";
4423 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
4424 }
4425
4426 // Test that when both the codec-specific bitrate params and max_bandwidth_bps
4427 // are present in the same send parameters, the settings are combined correctly.
TEST_F(WebRtcVideoChannelTest,SetSendCodecsWithBitratesAndMaxSendBandwidth)4428 TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitratesAndMaxSendBandwidth) {
4429 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
4430 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
4431 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
4432 send_parameters_.max_bandwidth_bps = 400000;
4433 // We expect max_bandwidth_bps to take priority, if set.
4434 ExpectSetBitrateParameters(100000, 200000, 400000);
4435 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
4436 // Since the codec isn't changing, start_bitrate_bps should be -1.
4437 ExpectSetBitrateParameters(100000, -1, 350000);
4438
4439 // Decrease max_bandwidth_bps.
4440 send_parameters_.max_bandwidth_bps = 350000;
4441 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
4442
4443 // Now try again with the values flipped around.
4444 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
4445 send_parameters_.max_bandwidth_bps = 300000;
4446 ExpectSetBitrateParameters(100000, 200000, 300000);
4447 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
4448
4449 // If we change the codec max, max_bandwidth_bps should still apply.
4450 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
4451 ExpectSetBitrateParameters(100000, 200000, 300000);
4452 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
4453 }
4454
TEST_F(WebRtcVideoChannelTest,SetMaxSendBandwidthShouldPreserveOtherBitrates)4455 TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldPreserveOtherBitrates) {
4456 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
4457 200000);
4458 send_parameters_.max_bandwidth_bps = 300000;
4459 // Setting max bitrate should keep previous min bitrate.
4460 // Setting max bitrate should not reset start bitrate.
4461 ExpectSetBitrateParameters(100000, -1, 300000);
4462 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
4463 }
4464
TEST_F(WebRtcVideoChannelTest,SetMaxSendBandwidthShouldBeRemovable)4465 TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldBeRemovable) {
4466 send_parameters_.max_bandwidth_bps = 300000;
4467 ExpectSetMaxBitrate(300000);
4468 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
4469 // -1 means to disable max bitrate (set infinite).
4470 send_parameters_.max_bandwidth_bps = -1;
4471 ExpectSetMaxBitrate(-1);
4472 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
4473 }
4474
TEST_F(WebRtcVideoChannelTest,SetMaxSendBandwidthAndAddSendStream)4475 TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthAndAddSendStream) {
4476 send_parameters_.max_bandwidth_bps = 99999;
4477 FakeVideoSendStream* stream = AddSendStream();
4478 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
4479 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4480 ASSERT_EQ(1u, stream->GetVideoStreams().size());
4481 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4482 stream->GetVideoStreams()[0].max_bitrate_bps);
4483
4484 send_parameters_.max_bandwidth_bps = 77777;
4485 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
4486 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4487 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4488 stream->GetVideoStreams()[0].max_bitrate_bps);
4489 }
4490
4491 // Tests that when the codec specific max bitrate and VideoSendParameters
4492 // max_bandwidth_bps are used, that it sets the VideoStream's max bitrate
4493 // appropriately.
TEST_F(WebRtcVideoChannelTest,MaxBitratePrioritizesVideoSendParametersOverCodecMaxBitrate)4494 TEST_F(WebRtcVideoChannelTest,
4495 MaxBitratePrioritizesVideoSendParametersOverCodecMaxBitrate) {
4496 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
4497 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
4498 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
4499 send_parameters_.max_bandwidth_bps = -1;
4500 AddSendStream();
4501 ExpectSetMaxBitrate(300000);
4502 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4503
4504 std::vector<FakeVideoSendStream*> video_send_streams = GetFakeSendStreams();
4505 ASSERT_EQ(1u, video_send_streams.size());
4506 FakeVideoSendStream* video_send_stream = video_send_streams[0];
4507 ASSERT_EQ(1u, video_send_streams[0]->GetVideoStreams().size());
4508 // First the max bitrate is set based upon the codec param.
4509 EXPECT_EQ(300000,
4510 video_send_streams[0]->GetVideoStreams()[0].max_bitrate_bps);
4511
4512 // The VideoSendParameters max bitrate overrides the codec's.
4513 send_parameters_.max_bandwidth_bps = 500000;
4514 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
4515 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4516 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4517 EXPECT_EQ(500000, video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4518 }
4519
4520 // Tests that when the codec specific max bitrate and RtpParameters
4521 // max_bitrate_bps are used, that it sets the VideoStream's max bitrate
4522 // appropriately.
TEST_F(WebRtcVideoChannelTest,MaxBitratePrioritizesRtpParametersOverCodecMaxBitrate)4523 TEST_F(WebRtcVideoChannelTest,
4524 MaxBitratePrioritizesRtpParametersOverCodecMaxBitrate) {
4525 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
4526 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
4527 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
4528 send_parameters_.max_bandwidth_bps = -1;
4529 AddSendStream();
4530 ExpectSetMaxBitrate(300000);
4531 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4532
4533 std::vector<FakeVideoSendStream*> video_send_streams = GetFakeSendStreams();
4534 ASSERT_EQ(1u, video_send_streams.size());
4535 FakeVideoSendStream* video_send_stream = video_send_streams[0];
4536 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4537 // First the max bitrate is set based upon the codec param.
4538 EXPECT_EQ(300000, video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4539
4540 // The RtpParameter max bitrate overrides the codec's.
4541 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
4542 ASSERT_EQ(1u, parameters.encodings.size());
4543 parameters.encodings[0].max_bitrate_bps = 500000;
4544 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4545 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4546 EXPECT_EQ(parameters.encodings[0].max_bitrate_bps,
4547 video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4548 }
4549
TEST_F(WebRtcVideoChannelTest,MaxBitrateIsMinimumOfMaxSendBandwidthAndMaxEncodingBitrate)4550 TEST_F(WebRtcVideoChannelTest,
4551 MaxBitrateIsMinimumOfMaxSendBandwidthAndMaxEncodingBitrate) {
4552 send_parameters_.max_bandwidth_bps = 99999;
4553 FakeVideoSendStream* stream = AddSendStream();
4554 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
4555 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4556 ASSERT_EQ(1u, stream->GetVideoStreams().size());
4557 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4558 stream->GetVideoStreams()[0].max_bitrate_bps);
4559
4560 // Get and set the rtp encoding parameters.
4561 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
4562 EXPECT_EQ(1u, parameters.encodings.size());
4563
4564 parameters.encodings[0].max_bitrate_bps = 99999 - 1;
4565 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4566 EXPECT_EQ(parameters.encodings[0].max_bitrate_bps,
4567 stream->GetVideoStreams()[0].max_bitrate_bps);
4568
4569 parameters.encodings[0].max_bitrate_bps = 99999 + 1;
4570 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4571 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4572 stream->GetVideoStreams()[0].max_bitrate_bps);
4573 }
4574
TEST_F(WebRtcVideoChannelTest,SetMaxSendBitrateCanIncreaseSenderBitrate)4575 TEST_F(WebRtcVideoChannelTest, SetMaxSendBitrateCanIncreaseSenderBitrate) {
4576 cricket::VideoSendParameters parameters;
4577 parameters.codecs.push_back(GetEngineCodec("VP8"));
4578 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4579 channel_->SetSend(true);
4580
4581 FakeVideoSendStream* stream = AddSendStream();
4582
4583 webrtc::test::FrameForwarder frame_forwarder;
4584 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
4585
4586 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
4587 int initial_max_bitrate_bps = streams[0].max_bitrate_bps;
4588 EXPECT_GT(initial_max_bitrate_bps, 0);
4589
4590 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
4591 EXPECT_TRUE(channel_->SetSendParameters(parameters));
4592 // Insert a frame to update the encoder config.
4593 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
4594 streams = stream->GetVideoStreams();
4595 EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps);
4596 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
4597 }
4598
TEST_F(WebRtcVideoChannelTest,SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate)4599 TEST_F(WebRtcVideoChannelTest,
4600 SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) {
4601 cricket::VideoSendParameters parameters;
4602 parameters.codecs.push_back(GetEngineCodec("VP8"));
4603 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4604 channel_->SetSend(true);
4605
4606 FakeVideoSendStream* stream = AddSendStream(
4607 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
4608
4609 // Send a frame to make sure this scales up to >1 stream (simulcast).
4610 webrtc::test::FrameForwarder frame_forwarder;
4611 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], nullptr, &frame_forwarder));
4612 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
4613
4614 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
4615 ASSERT_GT(streams.size(), 1u)
4616 << "Without simulcast this test doesn't make sense.";
4617 int initial_max_bitrate_bps = GetTotalMaxBitrate(streams).bps();
4618 EXPECT_GT(initial_max_bitrate_bps, 0);
4619
4620 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
4621 EXPECT_TRUE(channel_->SetSendParameters(parameters));
4622 // Insert a frame to update the encoder config.
4623 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
4624 streams = stream->GetVideoStreams();
4625 int increased_max_bitrate_bps = GetTotalMaxBitrate(streams).bps();
4626 EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps);
4627
4628 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], nullptr, nullptr));
4629 }
4630
TEST_F(WebRtcVideoChannelTest,SetSendCodecsWithMaxQuantization)4631 TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithMaxQuantization) {
4632 static const char* kMaxQuantization = "21";
4633 cricket::VideoSendParameters parameters;
4634 parameters.codecs.push_back(GetEngineCodec("VP8"));
4635 parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
4636 EXPECT_TRUE(channel_->SetSendParameters(parameters));
4637 EXPECT_EQ(atoi(kMaxQuantization),
4638 AddSendStream()->GetVideoStreams().back().max_qp);
4639
4640 VideoCodec codec;
4641 EXPECT_TRUE(channel_->GetSendCodec(&codec));
4642 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
4643 }
4644
TEST_F(WebRtcVideoChannelTest,SetSendCodecsRejectBadPayloadTypes)4645 TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectBadPayloadTypes) {
4646 // TODO(pbos): Should we only allow the dynamic range?
4647 static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
4648 cricket::VideoSendParameters parameters;
4649 parameters.codecs.push_back(GetEngineCodec("VP8"));
4650 for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
4651 parameters.codecs[0].id = kIncorrectPayloads[i];
4652 EXPECT_FALSE(channel_->SetSendParameters(parameters))
4653 << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted.";
4654 }
4655 }
4656
TEST_F(WebRtcVideoChannelTest,SetSendCodecsAcceptAllValidPayloadTypes)4657 TEST_F(WebRtcVideoChannelTest, SetSendCodecsAcceptAllValidPayloadTypes) {
4658 cricket::VideoSendParameters parameters;
4659 parameters.codecs.push_back(GetEngineCodec("VP8"));
4660 for (int payload_type = 96; payload_type <= 127; ++payload_type) {
4661 parameters.codecs[0].id = payload_type;
4662 EXPECT_TRUE(channel_->SetSendParameters(parameters))
4663 << "Payload type '" << payload_type << "' rejected.";
4664 }
4665 }
4666
4667 // Test that setting the a different set of codecs but with an identical front
4668 // codec doesn't result in the stream being recreated.
4669 // This may happen when a subsequent negotiation includes fewer codecs, as a
4670 // result of one of the codecs being rejected.
TEST_F(WebRtcVideoChannelTest,SetSendCodecsIdenticalFirstCodecDoesntRecreateStream)4671 TEST_F(WebRtcVideoChannelTest,
4672 SetSendCodecsIdenticalFirstCodecDoesntRecreateStream) {
4673 cricket::VideoSendParameters parameters1;
4674 parameters1.codecs.push_back(GetEngineCodec("VP8"));
4675 parameters1.codecs.push_back(GetEngineCodec("VP9"));
4676 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
4677
4678 AddSendStream();
4679 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
4680
4681 cricket::VideoSendParameters parameters2;
4682 parameters2.codecs.push_back(GetEngineCodec("VP8"));
4683 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
4684 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
4685 }
4686
TEST_F(WebRtcVideoChannelTest,SetRecvCodecsWithOnlyVp8)4687 TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithOnlyVp8) {
4688 cricket::VideoRecvParameters parameters;
4689 parameters.codecs.push_back(GetEngineCodec("VP8"));
4690 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4691 }
4692
4693 // Test that we set our inbound RTX codecs properly.
TEST_F(WebRtcVideoChannelTest,SetRecvCodecsWithRtx)4694 TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithRtx) {
4695 const int kUnusedPayloadType1 = 126;
4696 const int kUnusedPayloadType2 = 127;
4697 EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType1));
4698 EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType2));
4699
4700 cricket::VideoRecvParameters parameters;
4701 parameters.codecs.push_back(GetEngineCodec("VP8"));
4702 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
4703 parameters.codecs.push_back(rtx_codec);
4704 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
4705 << "RTX codec without associated payload should be rejected.";
4706
4707 parameters.codecs[1].SetParam("apt", kUnusedPayloadType2);
4708 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
4709 << "RTX codec with invalid associated payload type should be rejected.";
4710
4711 parameters.codecs[1].SetParam("apt", GetEngineCodec("VP8").id);
4712 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4713
4714 cricket::VideoCodec rtx_codec2(kUnusedPayloadType2, "rtx");
4715 rtx_codec2.SetParam("apt", rtx_codec.id);
4716 parameters.codecs.push_back(rtx_codec2);
4717
4718 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
4719 << "RTX codec with another RTX as associated payload type should be "
4720 "rejected.";
4721 }
4722
TEST_F(WebRtcVideoChannelTest,SetRecvCodecsWithPacketization)4723 TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithPacketization) {
4724 cricket::VideoCodec vp8_codec = GetEngineCodec("VP8");
4725 vp8_codec.packetization = kPacketizationParamRaw;
4726
4727 cricket::VideoRecvParameters parameters;
4728 parameters.codecs = {vp8_codec, GetEngineCodec("VP9")};
4729 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4730
4731 const cricket::StreamParams params =
4732 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
4733 AddRecvStream(params);
4734 ASSERT_THAT(fake_call_->GetVideoReceiveStreams(), testing::SizeIs(1));
4735
4736 const webrtc::VideoReceiveStream::Config& config =
4737 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
4738 ASSERT_THAT(config.rtp.raw_payload_types, testing::SizeIs(1));
4739 EXPECT_EQ(config.rtp.raw_payload_types.count(vp8_codec.id), 1U);
4740 }
4741
TEST_F(WebRtcVideoChannelTest,SetRecvCodecsWithPacketizationRecreatesStream)4742 TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithPacketizationRecreatesStream) {
4743 cricket::VideoRecvParameters parameters;
4744 parameters.codecs = {GetEngineCodec("VP8"), GetEngineCodec("VP9")};
4745 parameters.codecs.back().packetization = kPacketizationParamRaw;
4746 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4747
4748 const cricket::StreamParams params =
4749 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
4750 AddRecvStream(params);
4751 ASSERT_THAT(fake_call_->GetVideoReceiveStreams(), testing::SizeIs(1));
4752 EXPECT_EQ(fake_call_->GetNumCreatedReceiveStreams(), 1);
4753
4754 parameters.codecs.back().packetization.reset();
4755 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4756 EXPECT_EQ(fake_call_->GetNumCreatedReceiveStreams(), 2);
4757 }
4758
TEST_F(WebRtcVideoChannelTest,DuplicateUlpfecCodecIsDropped)4759 TEST_F(WebRtcVideoChannelTest, DuplicateUlpfecCodecIsDropped) {
4760 constexpr int kFirstUlpfecPayloadType = 126;
4761 constexpr int kSecondUlpfecPayloadType = 127;
4762
4763 cricket::VideoRecvParameters parameters;
4764 parameters.codecs.push_back(GetEngineCodec("VP8"));
4765 parameters.codecs.push_back(
4766 cricket::VideoCodec(kFirstUlpfecPayloadType, cricket::kUlpfecCodecName));
4767 parameters.codecs.push_back(
4768 cricket::VideoCodec(kSecondUlpfecPayloadType, cricket::kUlpfecCodecName));
4769 ASSERT_TRUE(channel_->SetRecvParameters(parameters));
4770
4771 FakeVideoReceiveStream* recv_stream = AddRecvStream();
4772 EXPECT_EQ(kFirstUlpfecPayloadType,
4773 recv_stream->GetConfig().rtp.ulpfec_payload_type);
4774 }
4775
TEST_F(WebRtcVideoChannelTest,DuplicateRedCodecIsDropped)4776 TEST_F(WebRtcVideoChannelTest, DuplicateRedCodecIsDropped) {
4777 constexpr int kFirstRedPayloadType = 126;
4778 constexpr int kSecondRedPayloadType = 127;
4779
4780 cricket::VideoRecvParameters parameters;
4781 parameters.codecs.push_back(GetEngineCodec("VP8"));
4782 parameters.codecs.push_back(
4783 cricket::VideoCodec(kFirstRedPayloadType, cricket::kRedCodecName));
4784 parameters.codecs.push_back(
4785 cricket::VideoCodec(kSecondRedPayloadType, cricket::kRedCodecName));
4786 ASSERT_TRUE(channel_->SetRecvParameters(parameters));
4787
4788 FakeVideoReceiveStream* recv_stream = AddRecvStream();
4789 EXPECT_EQ(kFirstRedPayloadType,
4790 recv_stream->GetConfig().rtp.red_payload_type);
4791 }
4792
TEST_F(WebRtcVideoChannelTest,SetRecvCodecsWithChangedRtxPayloadType)4793 TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithChangedRtxPayloadType) {
4794 const int kUnusedPayloadType1 = 126;
4795 const int kUnusedPayloadType2 = 127;
4796 EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType1));
4797 EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType2));
4798
4799 // SSRCs for RTX.
4800 cricket::StreamParams params =
4801 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
4802 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
4803 AddRecvStream(params);
4804
4805 // Original payload type for RTX.
4806 cricket::VideoRecvParameters parameters;
4807 parameters.codecs.push_back(GetEngineCodec("VP8"));
4808 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
4809 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
4810 parameters.codecs.push_back(rtx_codec);
4811 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4812 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
4813 const webrtc::VideoReceiveStream::Config& config_before =
4814 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
4815 EXPECT_EQ(1U, config_before.rtp.rtx_associated_payload_types.size());
4816 const int* payload_type_before = FindKeyByValue(
4817 config_before.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
4818 ASSERT_NE(payload_type_before, nullptr);
4819 EXPECT_EQ(kUnusedPayloadType1, *payload_type_before);
4820 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx_ssrc);
4821
4822 // Change payload type for RTX.
4823 parameters.codecs[1].id = kUnusedPayloadType2;
4824 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4825 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
4826 const webrtc::VideoReceiveStream::Config& config_after =
4827 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
4828 EXPECT_EQ(1U, config_after.rtp.rtx_associated_payload_types.size());
4829 const int* payload_type_after = FindKeyByValue(
4830 config_after.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
4831 ASSERT_NE(payload_type_after, nullptr);
4832 EXPECT_EQ(kUnusedPayloadType2, *payload_type_after);
4833 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx_ssrc);
4834 }
4835
TEST_F(WebRtcVideoChannelTest,SetRecvCodecsDifferentPayloadType)4836 TEST_F(WebRtcVideoChannelTest, SetRecvCodecsDifferentPayloadType) {
4837 cricket::VideoRecvParameters parameters;
4838 parameters.codecs.push_back(GetEngineCodec("VP8"));
4839 parameters.codecs[0].id = 99;
4840 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4841 }
4842
TEST_F(WebRtcVideoChannelTest,SetRecvCodecsAcceptDefaultCodecs)4843 TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptDefaultCodecs) {
4844 cricket::VideoRecvParameters parameters;
4845 parameters.codecs = engine_.recv_codecs();
4846 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4847
4848 FakeVideoReceiveStream* stream = AddRecvStream();
4849 const webrtc::VideoReceiveStream::Config& config = stream->GetConfig();
4850 EXPECT_EQ(engine_.recv_codecs()[0].name,
4851 config.decoders[0].video_format.name);
4852 EXPECT_EQ(engine_.recv_codecs()[0].id, config.decoders[0].payload_type);
4853 }
4854
TEST_F(WebRtcVideoChannelTest,SetRecvCodecsRejectUnsupportedCodec)4855 TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectUnsupportedCodec) {
4856 cricket::VideoRecvParameters parameters;
4857 parameters.codecs.push_back(GetEngineCodec("VP8"));
4858 parameters.codecs.push_back(VideoCodec(101, "WTF3"));
4859 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
4860 }
4861
TEST_F(WebRtcVideoChannelTest,SetRecvCodecsAcceptsMultipleVideoCodecs)4862 TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptsMultipleVideoCodecs) {
4863 cricket::VideoRecvParameters parameters;
4864 parameters.codecs.push_back(GetEngineCodec("VP8"));
4865 parameters.codecs.push_back(GetEngineCodec("VP9"));
4866 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4867 }
4868
TEST_F(WebRtcVideoChannelTest,SetRecvCodecsWithoutFecDisablesFec)4869 TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithoutFecDisablesFec) {
4870 cricket::VideoSendParameters send_parameters;
4871 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4872 send_parameters.codecs.push_back(GetEngineCodec("red"));
4873 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
4874 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
4875
4876 FakeVideoReceiveStream* stream = AddRecvStream();
4877
4878 EXPECT_EQ(GetEngineCodec("ulpfec").id,
4879 stream->GetConfig().rtp.ulpfec_payload_type);
4880
4881 cricket::VideoRecvParameters recv_parameters;
4882 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4883 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4884 stream = fake_call_->GetVideoReceiveStreams()[0];
4885 ASSERT_TRUE(stream != nullptr);
4886 EXPECT_EQ(-1, stream->GetConfig().rtp.ulpfec_payload_type)
4887 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
4888 }
4889
TEST_F(WebRtcVideoChannelFlexfecRecvTest,SetRecvParamsWithoutFecDisablesFec)4890 TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvParamsWithoutFecDisablesFec) {
4891 AddRecvStream(
4892 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4893 const std::vector<FakeFlexfecReceiveStream*>& streams =
4894 fake_call_->GetFlexfecReceiveStreams();
4895
4896 ASSERT_EQ(1U, streams.size());
4897 const FakeFlexfecReceiveStream* stream = streams.front();
4898 EXPECT_EQ(GetEngineCodec("flexfec-03").id, stream->GetConfig().payload_type);
4899 EXPECT_EQ(kFlexfecSsrc, stream->GetConfig().remote_ssrc);
4900 ASSERT_EQ(1U, stream->GetConfig().protected_media_ssrcs.size());
4901 EXPECT_EQ(kSsrcs1[0], stream->GetConfig().protected_media_ssrcs[0]);
4902
4903 cricket::VideoRecvParameters recv_parameters;
4904 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4905 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4906 EXPECT_TRUE(streams.empty())
4907 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
4908 }
4909
TEST_F(WebRtcVideoChannelTest,SetSendParamsWithFecEnablesFec)4910 TEST_F(WebRtcVideoChannelTest, SetSendParamsWithFecEnablesFec) {
4911 FakeVideoReceiveStream* stream = AddRecvStream();
4912 EXPECT_EQ(GetEngineCodec("ulpfec").id,
4913 stream->GetConfig().rtp.ulpfec_payload_type);
4914
4915 cricket::VideoRecvParameters recv_parameters;
4916 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4917 recv_parameters.codecs.push_back(GetEngineCodec("red"));
4918 recv_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
4919 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4920 stream = fake_call_->GetVideoReceiveStreams()[0];
4921 ASSERT_TRUE(stream != nullptr);
4922 EXPECT_EQ(GetEngineCodec("ulpfec").id,
4923 stream->GetConfig().rtp.ulpfec_payload_type)
4924 << "ULPFEC should be enabled on the receive stream.";
4925
4926 cricket::VideoSendParameters send_parameters;
4927 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4928 send_parameters.codecs.push_back(GetEngineCodec("red"));
4929 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
4930 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
4931 stream = fake_call_->GetVideoReceiveStreams()[0];
4932 EXPECT_EQ(GetEngineCodec("ulpfec").id,
4933 stream->GetConfig().rtp.ulpfec_payload_type)
4934 << "ULPFEC should be enabled on the receive stream.";
4935 }
4936
TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,SetSendRecvParamsWithFecEnablesFec)4937 TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
4938 SetSendRecvParamsWithFecEnablesFec) {
4939 AddRecvStream(
4940 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4941 const std::vector<FakeFlexfecReceiveStream*>& streams =
4942 fake_call_->GetFlexfecReceiveStreams();
4943
4944 cricket::VideoRecvParameters recv_parameters;
4945 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4946 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4947 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4948 ASSERT_EQ(1U, streams.size());
4949 const FakeFlexfecReceiveStream* stream_with_recv_params = streams.front();
4950 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
4951 stream_with_recv_params->GetConfig().payload_type);
4952 EXPECT_EQ(kFlexfecSsrc, stream_with_recv_params->GetConfig().remote_ssrc);
4953 EXPECT_EQ(1U,
4954 stream_with_recv_params->GetConfig().protected_media_ssrcs.size());
4955 EXPECT_EQ(kSsrcs1[0],
4956 stream_with_recv_params->GetConfig().protected_media_ssrcs[0]);
4957
4958 cricket::VideoSendParameters send_parameters;
4959 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4960 send_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4961 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
4962 ASSERT_EQ(1U, streams.size());
4963 const FakeFlexfecReceiveStream* stream_with_send_params = streams.front();
4964 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
4965 stream_with_send_params->GetConfig().payload_type);
4966 EXPECT_EQ(kFlexfecSsrc, stream_with_send_params->GetConfig().remote_ssrc);
4967 EXPECT_EQ(1U,
4968 stream_with_send_params->GetConfig().protected_media_ssrcs.size());
4969 EXPECT_EQ(kSsrcs1[0],
4970 stream_with_send_params->GetConfig().protected_media_ssrcs[0]);
4971 }
4972
TEST_F(WebRtcVideoChannelTest,SetRecvCodecsRejectDuplicateFecPayloads)4973 TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateFecPayloads) {
4974 cricket::VideoRecvParameters parameters;
4975 parameters.codecs.push_back(GetEngineCodec("VP8"));
4976 parameters.codecs.push_back(GetEngineCodec("red"));
4977 parameters.codecs[1].id = parameters.codecs[0].id;
4978 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
4979 }
4980
TEST_F(WebRtcVideoChannelFlexfecRecvTest,SetRecvCodecsRejectDuplicateFecPayloads)4981 TEST_F(WebRtcVideoChannelFlexfecRecvTest,
4982 SetRecvCodecsRejectDuplicateFecPayloads) {
4983 cricket::VideoRecvParameters parameters;
4984 parameters.codecs.push_back(GetEngineCodec("VP8"));
4985 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4986 parameters.codecs[1].id = parameters.codecs[0].id;
4987 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
4988 }
4989
TEST_F(WebRtcVideoChannelTest,SetRecvCodecsRejectDuplicateCodecPayloads)4990 TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateCodecPayloads) {
4991 cricket::VideoRecvParameters parameters;
4992 parameters.codecs.push_back(GetEngineCodec("VP8"));
4993 parameters.codecs.push_back(GetEngineCodec("VP9"));
4994 parameters.codecs[1].id = parameters.codecs[0].id;
4995 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
4996 }
4997
TEST_F(WebRtcVideoChannelTest,SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes)4998 TEST_F(WebRtcVideoChannelTest,
4999 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
5000 cricket::VideoRecvParameters parameters;
5001 parameters.codecs.push_back(GetEngineCodec("VP8"));
5002 parameters.codecs.push_back(GetEngineCodec("VP8"));
5003 parameters.codecs[1].id += 1;
5004 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
5005 }
5006
5007 // Test that setting the same codecs but with a different order
5008 // doesn't result in the stream being recreated.
TEST_F(WebRtcVideoChannelTest,SetRecvCodecsDifferentOrderDoesntRecreateStream)5009 TEST_F(WebRtcVideoChannelTest,
5010 SetRecvCodecsDifferentOrderDoesntRecreateStream) {
5011 cricket::VideoRecvParameters parameters1;
5012 parameters1.codecs.push_back(GetEngineCodec("VP8"));
5013 parameters1.codecs.push_back(GetEngineCodec("red"));
5014 EXPECT_TRUE(channel_->SetRecvParameters(parameters1));
5015
5016 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
5017 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
5018
5019 cricket::VideoRecvParameters parameters2;
5020 parameters2.codecs.push_back(GetEngineCodec("red"));
5021 parameters2.codecs.push_back(GetEngineCodec("VP8"));
5022 EXPECT_TRUE(channel_->SetRecvParameters(parameters2));
5023 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
5024 }
5025
TEST_F(WebRtcVideoChannelTest,SendStreamNotSendingByDefault)5026 TEST_F(WebRtcVideoChannelTest, SendStreamNotSendingByDefault) {
5027 EXPECT_FALSE(AddSendStream()->IsSending());
5028 }
5029
TEST_F(WebRtcVideoChannelTest,ReceiveStreamReceivingByDefault)5030 TEST_F(WebRtcVideoChannelTest, ReceiveStreamReceivingByDefault) {
5031 EXPECT_TRUE(AddRecvStream()->IsReceiving());
5032 }
5033
TEST_F(WebRtcVideoChannelTest,SetSend)5034 TEST_F(WebRtcVideoChannelTest, SetSend) {
5035 FakeVideoSendStream* stream = AddSendStream();
5036 EXPECT_FALSE(stream->IsSending());
5037
5038 // false->true
5039 EXPECT_TRUE(channel_->SetSend(true));
5040 EXPECT_TRUE(stream->IsSending());
5041 // true->true
5042 EXPECT_TRUE(channel_->SetSend(true));
5043 EXPECT_TRUE(stream->IsSending());
5044 // true->false
5045 EXPECT_TRUE(channel_->SetSend(false));
5046 EXPECT_FALSE(stream->IsSending());
5047 // false->false
5048 EXPECT_TRUE(channel_->SetSend(false));
5049 EXPECT_FALSE(stream->IsSending());
5050
5051 EXPECT_TRUE(channel_->SetSend(true));
5052 FakeVideoSendStream* new_stream = AddSendStream();
5053 EXPECT_TRUE(new_stream->IsSending())
5054 << "Send stream created after SetSend(true) not sending initially.";
5055 }
5056
5057 // This test verifies DSCP settings are properly applied on video media channel.
TEST_F(WebRtcVideoChannelTest,TestSetDscpOptions)5058 TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
5059 std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
5060 new cricket::FakeNetworkInterface);
5061 MediaConfig config;
5062 std::unique_ptr<cricket::WebRtcVideoChannel> channel;
5063 webrtc::RtpParameters parameters;
5064
5065 channel.reset(
5066 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
5067 call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
5068 video_bitrate_allocator_factory_.get())));
5069 channel->SetInterface(network_interface.get());
5070 // Default value when DSCP is disabled should be DSCP_DEFAULT.
5071 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
5072
5073 // Default value when DSCP is enabled is also DSCP_DEFAULT, until it is set
5074 // through rtp parameters.
5075 config.enable_dscp = true;
5076 channel.reset(
5077 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
5078 call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
5079 video_bitrate_allocator_factory_.get())));
5080 channel->SetInterface(network_interface.get());
5081 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
5082
5083 // Create a send stream to configure
5084 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
5085 parameters = channel->GetRtpSendParameters(kSsrc);
5086 ASSERT_FALSE(parameters.encodings.empty());
5087
5088 // Various priorities map to various dscp values.
5089 parameters.encodings[0].network_priority = webrtc::Priority::kHigh;
5090 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
5091 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
5092 parameters.encodings[0].network_priority = webrtc::Priority::kVeryLow;
5093 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
5094 EXPECT_EQ(rtc::DSCP_CS1, network_interface->dscp());
5095
5096 // Packets should also self-identify their dscp in PacketOptions.
5097 const uint8_t kData[10] = {0};
5098 EXPECT_TRUE(static_cast<webrtc::Transport*>(channel.get())
5099 ->SendRtcp(kData, sizeof(kData)));
5100 EXPECT_EQ(rtc::DSCP_CS1, network_interface->options().dscp);
5101
5102 // Verify that setting the option to false resets the
5103 // DiffServCodePoint.
5104 config.enable_dscp = false;
5105 channel.reset(
5106 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
5107 call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
5108 video_bitrate_allocator_factory_.get())));
5109 channel->SetInterface(network_interface.get());
5110 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
5111 }
5112
5113 // This test verifies that the RTCP reduced size mode is properly applied to
5114 // send video streams.
TEST_F(WebRtcVideoChannelTest,TestSetSendRtcpReducedSize)5115 TEST_F(WebRtcVideoChannelTest, TestSetSendRtcpReducedSize) {
5116 // Create stream, expecting that default mode is "compound".
5117 FakeVideoSendStream* stream1 = AddSendStream();
5118 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
5119 webrtc::RtpParameters rtp_parameters =
5120 channel_->GetRtpSendParameters(last_ssrc_);
5121 EXPECT_FALSE(rtp_parameters.rtcp.reduced_size);
5122
5123 // Now enable reduced size mode.
5124 send_parameters_.rtcp.reduced_size = true;
5125 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
5126 stream1 = fake_call_->GetVideoSendStreams()[0];
5127 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
5128 rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5129 EXPECT_TRUE(rtp_parameters.rtcp.reduced_size);
5130
5131 // Create a new stream and ensure it picks up the reduced size mode.
5132 FakeVideoSendStream* stream2 = AddSendStream();
5133 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
5134 }
5135
5136 // This test verifies that the RTCP reduced size mode is properly applied to
5137 // receive video streams.
TEST_F(WebRtcVideoChannelTest,TestSetRecvRtcpReducedSize)5138 TEST_F(WebRtcVideoChannelTest, TestSetRecvRtcpReducedSize) {
5139 // Create stream, expecting that default mode is "compound".
5140 FakeVideoReceiveStream* stream1 = AddRecvStream();
5141 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
5142
5143 // Now enable reduced size mode.
5144 // TODO(deadbeef): Once "recv_parameters" becomes "receiver_parameters",
5145 // the reduced_size flag should come from that.
5146 send_parameters_.rtcp.reduced_size = true;
5147 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
5148 stream1 = fake_call_->GetVideoReceiveStreams()[0];
5149 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
5150
5151 // Create a new stream and ensure it picks up the reduced size mode.
5152 FakeVideoReceiveStream* stream2 = AddRecvStream();
5153 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
5154 }
5155
TEST_F(WebRtcVideoChannelTest,OnReadyToSendSignalsNetworkState)5156 TEST_F(WebRtcVideoChannelTest, OnReadyToSendSignalsNetworkState) {
5157 EXPECT_EQ(webrtc::kNetworkUp,
5158 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
5159 EXPECT_EQ(webrtc::kNetworkUp,
5160 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
5161
5162 channel_->OnReadyToSend(false);
5163 EXPECT_EQ(webrtc::kNetworkDown,
5164 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
5165 EXPECT_EQ(webrtc::kNetworkUp,
5166 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
5167
5168 channel_->OnReadyToSend(true);
5169 EXPECT_EQ(webrtc::kNetworkUp,
5170 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
5171 EXPECT_EQ(webrtc::kNetworkUp,
5172 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
5173 }
5174
TEST_F(WebRtcVideoChannelTest,GetStatsReportsSentCodecName)5175 TEST_F(WebRtcVideoChannelTest, GetStatsReportsSentCodecName) {
5176 cricket::VideoSendParameters parameters;
5177 parameters.codecs.push_back(GetEngineCodec("VP8"));
5178 EXPECT_TRUE(channel_->SetSendParameters(parameters));
5179
5180 AddSendStream();
5181
5182 cricket::VideoMediaInfo info;
5183 ASSERT_TRUE(channel_->GetStats(&info));
5184 EXPECT_EQ("VP8", info.senders[0].codec_name);
5185 }
5186
TEST_F(WebRtcVideoChannelTest,GetStatsReportsEncoderImplementationName)5187 TEST_F(WebRtcVideoChannelTest, GetStatsReportsEncoderImplementationName) {
5188 FakeVideoSendStream* stream = AddSendStream();
5189 webrtc::VideoSendStream::Stats stats;
5190 stats.encoder_implementation_name = "encoder_implementation_name";
5191 stream->SetStats(stats);
5192
5193 cricket::VideoMediaInfo info;
5194 ASSERT_TRUE(channel_->GetStats(&info));
5195 EXPECT_EQ(stats.encoder_implementation_name,
5196 info.senders[0].encoder_implementation_name);
5197 }
5198
TEST_F(WebRtcVideoChannelTest,GetStatsReportsCpuOveruseMetrics)5199 TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuOveruseMetrics) {
5200 FakeVideoSendStream* stream = AddSendStream();
5201 webrtc::VideoSendStream::Stats stats;
5202 stats.avg_encode_time_ms = 13;
5203 stats.encode_usage_percent = 42;
5204 stream->SetStats(stats);
5205
5206 cricket::VideoMediaInfo info;
5207 ASSERT_TRUE(channel_->GetStats(&info));
5208 EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
5209 EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
5210 }
5211
TEST_F(WebRtcVideoChannelTest,GetStatsReportsFramesEncoded)5212 TEST_F(WebRtcVideoChannelTest, GetStatsReportsFramesEncoded) {
5213 FakeVideoSendStream* stream = AddSendStream();
5214 webrtc::VideoSendStream::Stats stats;
5215 stats.frames_encoded = 13;
5216 stream->SetStats(stats);
5217
5218 cricket::VideoMediaInfo info;
5219 ASSERT_TRUE(channel_->GetStats(&info));
5220 EXPECT_EQ(stats.frames_encoded, info.senders[0].frames_encoded);
5221 }
5222
TEST_F(WebRtcVideoChannelTest,GetStatsReportsKeyFramesEncoded)5223 TEST_F(WebRtcVideoChannelTest, GetStatsReportsKeyFramesEncoded) {
5224 FakeVideoSendStream* stream = AddSendStream();
5225 webrtc::VideoSendStream::Stats stats;
5226 stats.substreams[123].frame_counts.key_frames = 10;
5227 stats.substreams[456].frame_counts.key_frames = 87;
5228 stream->SetStats(stats);
5229
5230 cricket::VideoMediaInfo info;
5231 ASSERT_TRUE(channel_->GetStats(&info));
5232 EXPECT_EQ(info.senders.size(), 2u);
5233 EXPECT_EQ(10u, info.senders[0].key_frames_encoded);
5234 EXPECT_EQ(87u, info.senders[1].key_frames_encoded);
5235 EXPECT_EQ(97u, info.aggregated_senders[0].key_frames_encoded);
5236 }
5237
TEST_F(WebRtcVideoChannelTest,GetStatsReportsPerLayerQpSum)5238 TEST_F(WebRtcVideoChannelTest, GetStatsReportsPerLayerQpSum) {
5239 FakeVideoSendStream* stream = AddSendStream();
5240 webrtc::VideoSendStream::Stats stats;
5241 stats.substreams[123].qp_sum = 15;
5242 stats.substreams[456].qp_sum = 11;
5243 stream->SetStats(stats);
5244
5245 cricket::VideoMediaInfo info;
5246 ASSERT_TRUE(channel_->GetStats(&info));
5247 EXPECT_EQ(info.senders.size(), 2u);
5248 EXPECT_EQ(stats.substreams[123].qp_sum, info.senders[0].qp_sum);
5249 EXPECT_EQ(stats.substreams[456].qp_sum, info.senders[1].qp_sum);
5250 EXPECT_EQ(*info.aggregated_senders[0].qp_sum, 26u);
5251 }
5252
GetInitialisedStats()5253 webrtc::VideoSendStream::Stats GetInitialisedStats() {
5254 webrtc::VideoSendStream::Stats stats;
5255 stats.encoder_implementation_name = "vp";
5256 stats.input_frame_rate = 1;
5257 stats.encode_frame_rate = 2;
5258 stats.avg_encode_time_ms = 3;
5259 stats.encode_usage_percent = 4;
5260 stats.frames_encoded = 5;
5261 stats.total_encode_time_ms = 6;
5262 stats.frames_dropped_by_capturer = 7;
5263 stats.frames_dropped_by_encoder_queue = 8;
5264 stats.frames_dropped_by_rate_limiter = 9;
5265 stats.frames_dropped_by_congestion_window = 10;
5266 stats.frames_dropped_by_encoder = 11;
5267 stats.target_media_bitrate_bps = 13;
5268 stats.media_bitrate_bps = 14;
5269 stats.suspended = true;
5270 stats.bw_limited_resolution = true;
5271 stats.cpu_limited_resolution = true;
5272 // Not wired.
5273 stats.bw_limited_framerate = true;
5274 // Not wired.
5275 stats.cpu_limited_framerate = true;
5276 stats.quality_limitation_reason = webrtc::QualityLimitationReason::kCpu;
5277 stats.quality_limitation_durations_ms[webrtc::QualityLimitationReason::kCpu] =
5278 15;
5279 stats.quality_limitation_resolution_changes = 16;
5280 stats.number_of_cpu_adapt_changes = 17;
5281 stats.number_of_quality_adapt_changes = 18;
5282 stats.has_entered_low_resolution = true;
5283 stats.content_type = webrtc::VideoContentType::SCREENSHARE;
5284 stats.frames_sent = 19;
5285 stats.huge_frames_sent = 20;
5286
5287 return stats;
5288 }
5289
TEST_F(WebRtcVideoChannelTest,GetAggregatedStatsReportWithoutSubStreams)5290 TEST_F(WebRtcVideoChannelTest, GetAggregatedStatsReportWithoutSubStreams) {
5291 FakeVideoSendStream* stream = AddSendStream();
5292 auto stats = GetInitialisedStats();
5293 stream->SetStats(stats);
5294 cricket::VideoMediaInfo video_media_info;
5295 ASSERT_TRUE(channel_->GetStats(&video_media_info));
5296 EXPECT_EQ(video_media_info.aggregated_senders.size(), 1u);
5297 auto& sender = video_media_info.aggregated_senders[0];
5298
5299 // MediaSenderInfo
5300
5301 EXPECT_EQ(sender.payload_bytes_sent, 0);
5302 EXPECT_EQ(sender.header_and_padding_bytes_sent, 0);
5303 EXPECT_EQ(sender.retransmitted_bytes_sent, 0u);
5304 EXPECT_EQ(sender.packets_sent, 0);
5305 EXPECT_EQ(sender.retransmitted_packets_sent, 0u);
5306 EXPECT_EQ(sender.packets_lost, 0);
5307 EXPECT_EQ(sender.fraction_lost, 0.0f);
5308 EXPECT_EQ(sender.rtt_ms, 0);
5309 EXPECT_EQ(sender.codec_name, DefaultCodec().name);
5310 EXPECT_EQ(sender.codec_payload_type, DefaultCodec().id);
5311 EXPECT_EQ(sender.local_stats.size(), 1u);
5312 EXPECT_EQ(sender.local_stats[0].ssrc, last_ssrc_);
5313 EXPECT_EQ(sender.local_stats[0].timestamp, 0.0f);
5314 EXPECT_EQ(sender.remote_stats.size(), 0u);
5315 EXPECT_EQ(sender.report_block_datas.size(), 0u);
5316
5317 // VideoSenderInfo
5318
5319 EXPECT_EQ(sender.ssrc_groups.size(), 0u);
5320 EXPECT_EQ(sender.encoder_implementation_name,
5321 stats.encoder_implementation_name);
5322 // Comes from substream only.
5323 EXPECT_EQ(sender.firs_rcvd, 0);
5324 EXPECT_EQ(sender.plis_rcvd, 0);
5325 EXPECT_EQ(sender.nacks_rcvd, 0);
5326 EXPECT_EQ(sender.send_frame_width, 0);
5327 EXPECT_EQ(sender.send_frame_height, 0);
5328
5329 EXPECT_EQ(sender.framerate_input, stats.input_frame_rate);
5330 EXPECT_EQ(sender.framerate_sent, stats.encode_frame_rate);
5331 EXPECT_EQ(sender.nominal_bitrate, stats.media_bitrate_bps);
5332 EXPECT_NE(sender.adapt_reason & WebRtcVideoChannel::ADAPTREASON_CPU, 0);
5333 EXPECT_NE(sender.adapt_reason & WebRtcVideoChannel::ADAPTREASON_BANDWIDTH, 0);
5334 EXPECT_EQ(sender.adapt_changes, stats.number_of_cpu_adapt_changes);
5335 EXPECT_EQ(sender.quality_limitation_reason, stats.quality_limitation_reason);
5336 EXPECT_EQ(sender.quality_limitation_durations_ms,
5337 stats.quality_limitation_durations_ms);
5338 EXPECT_EQ(sender.quality_limitation_resolution_changes,
5339 stats.quality_limitation_resolution_changes);
5340 EXPECT_EQ(sender.avg_encode_ms, stats.avg_encode_time_ms);
5341 EXPECT_EQ(sender.encode_usage_percent, stats.encode_usage_percent);
5342 EXPECT_EQ(sender.frames_encoded, stats.frames_encoded);
5343 // Comes from substream only.
5344 EXPECT_EQ(sender.key_frames_encoded, 0u);
5345
5346 EXPECT_EQ(sender.total_encode_time_ms, stats.total_encode_time_ms);
5347 EXPECT_EQ(sender.total_encoded_bytes_target,
5348 stats.total_encoded_bytes_target);
5349 // Comes from substream only.
5350 EXPECT_EQ(sender.total_packet_send_delay_ms, 0u);
5351 EXPECT_EQ(sender.qp_sum, absl::nullopt);
5352
5353 EXPECT_EQ(sender.has_entered_low_resolution,
5354 stats.has_entered_low_resolution);
5355 EXPECT_EQ(sender.content_type, webrtc::VideoContentType::SCREENSHARE);
5356 EXPECT_EQ(sender.frames_sent, stats.frames_encoded);
5357 EXPECT_EQ(sender.huge_frames_sent, stats.huge_frames_sent);
5358 EXPECT_EQ(sender.rid, absl::nullopt);
5359 }
5360
TEST_F(WebRtcVideoChannelTest,GetAggregatedStatsReportForSubStreams)5361 TEST_F(WebRtcVideoChannelTest, GetAggregatedStatsReportForSubStreams) {
5362 FakeVideoSendStream* stream = AddSendStream();
5363 auto stats = GetInitialisedStats();
5364
5365 const uint32_t ssrc_1 = 123u;
5366 const uint32_t ssrc_2 = 456u;
5367
5368 auto& substream = stats.substreams[ssrc_1];
5369 substream.frame_counts.key_frames = 1;
5370 substream.frame_counts.delta_frames = 2;
5371 substream.width = 3;
5372 substream.height = 4;
5373 substream.total_bitrate_bps = 5;
5374 substream.retransmit_bitrate_bps = 6;
5375 substream.avg_delay_ms = 7;
5376 substream.max_delay_ms = 8;
5377 substream.total_packet_send_delay_ms = 9;
5378 substream.rtp_stats.transmitted.header_bytes = 10;
5379 substream.rtp_stats.transmitted.padding_bytes = 11;
5380 substream.rtp_stats.retransmitted.payload_bytes = 12;
5381 substream.rtp_stats.retransmitted.packets = 13;
5382 substream.rtcp_packet_type_counts.fir_packets = 14;
5383 substream.rtcp_packet_type_counts.nack_packets = 15;
5384 substream.rtcp_packet_type_counts.pli_packets = 16;
5385 substream.rtcp_stats.packets_lost = 17;
5386 substream.rtcp_stats.fraction_lost = 18;
5387 webrtc::ReportBlockData report_block_data;
5388 report_block_data.AddRoundTripTimeSample(19);
5389 substream.report_block_data = report_block_data;
5390 substream.encode_frame_rate = 20.0;
5391 substream.frames_encoded = 21;
5392 substream.qp_sum = 22;
5393 substream.total_encode_time_ms = 23;
5394 substream.total_encoded_bytes_target = 24;
5395 substream.huge_frames_sent = 25;
5396
5397 stats.substreams[ssrc_2] = substream;
5398
5399 stream->SetStats(stats);
5400
5401 cricket::VideoMediaInfo video_media_info;
5402 ASSERT_TRUE(channel_->GetStats(&video_media_info));
5403 EXPECT_EQ(video_media_info.aggregated_senders.size(), 1u);
5404 auto& sender = video_media_info.aggregated_senders[0];
5405
5406 // MediaSenderInfo
5407
5408 EXPECT_EQ(
5409 sender.payload_bytes_sent,
5410 static_cast<int64_t>(2u * substream.rtp_stats.transmitted.payload_bytes));
5411 EXPECT_EQ(sender.header_and_padding_bytes_sent,
5412 static_cast<int64_t>(
5413 2u * (substream.rtp_stats.transmitted.header_bytes +
5414 substream.rtp_stats.transmitted.padding_bytes)));
5415 EXPECT_EQ(sender.retransmitted_bytes_sent,
5416 2u * substream.rtp_stats.retransmitted.payload_bytes);
5417 EXPECT_EQ(sender.packets_sent,
5418 static_cast<int>(2 * substream.rtp_stats.transmitted.packets));
5419 EXPECT_EQ(sender.retransmitted_packets_sent,
5420 2u * substream.rtp_stats.retransmitted.packets);
5421 EXPECT_EQ(sender.packets_lost, 2 * substream.rtcp_stats.packets_lost);
5422 EXPECT_EQ(sender.fraction_lost,
5423 static_cast<float>(substream.rtcp_stats.fraction_lost) / (1 << 8));
5424 EXPECT_EQ(sender.rtt_ms, 0);
5425 EXPECT_EQ(sender.codec_name, DefaultCodec().name);
5426 EXPECT_EQ(sender.codec_payload_type, DefaultCodec().id);
5427 EXPECT_EQ(sender.local_stats.size(), 1u);
5428 EXPECT_EQ(sender.local_stats[0].ssrc, last_ssrc_);
5429 EXPECT_EQ(sender.local_stats[0].timestamp, 0.0f);
5430 EXPECT_EQ(sender.remote_stats.size(), 0u);
5431 EXPECT_EQ(sender.report_block_datas.size(), 2u * 1);
5432
5433 // VideoSenderInfo
5434
5435 EXPECT_EQ(sender.ssrc_groups.size(), 0u);
5436 EXPECT_EQ(sender.encoder_implementation_name,
5437 stats.encoder_implementation_name);
5438 EXPECT_EQ(
5439 sender.firs_rcvd,
5440 static_cast<int>(2 * substream.rtcp_packet_type_counts.fir_packets));
5441 EXPECT_EQ(
5442 sender.plis_rcvd,
5443 static_cast<int>(2 * substream.rtcp_packet_type_counts.pli_packets));
5444 EXPECT_EQ(
5445 sender.nacks_rcvd,
5446 static_cast<int>(2 * substream.rtcp_packet_type_counts.nack_packets));
5447 EXPECT_EQ(sender.send_frame_width, substream.width);
5448 EXPECT_EQ(sender.send_frame_height, substream.height);
5449
5450 EXPECT_EQ(sender.framerate_input, stats.input_frame_rate);
5451 EXPECT_EQ(sender.framerate_sent, stats.encode_frame_rate);
5452 EXPECT_EQ(sender.nominal_bitrate, stats.media_bitrate_bps);
5453 EXPECT_NE(sender.adapt_reason & WebRtcVideoChannel::ADAPTREASON_CPU, 0);
5454 EXPECT_NE(sender.adapt_reason & WebRtcVideoChannel::ADAPTREASON_BANDWIDTH, 0);
5455 EXPECT_EQ(sender.adapt_changes, stats.number_of_cpu_adapt_changes);
5456 EXPECT_EQ(sender.quality_limitation_reason, stats.quality_limitation_reason);
5457 EXPECT_EQ(sender.quality_limitation_durations_ms,
5458 stats.quality_limitation_durations_ms);
5459 EXPECT_EQ(sender.quality_limitation_resolution_changes,
5460 stats.quality_limitation_resolution_changes);
5461 EXPECT_EQ(sender.avg_encode_ms, stats.avg_encode_time_ms);
5462 EXPECT_EQ(sender.encode_usage_percent, stats.encode_usage_percent);
5463 EXPECT_EQ(sender.frames_encoded, 2u * substream.frames_encoded);
5464 EXPECT_EQ(sender.key_frames_encoded, 2u * substream.frame_counts.key_frames);
5465 EXPECT_EQ(sender.total_encode_time_ms, 2u * substream.total_encode_time_ms);
5466 EXPECT_EQ(sender.total_encoded_bytes_target,
5467 2u * substream.total_encoded_bytes_target);
5468 EXPECT_EQ(sender.total_packet_send_delay_ms,
5469 2u * substream.total_packet_send_delay_ms);
5470 EXPECT_EQ(sender.has_entered_low_resolution,
5471 stats.has_entered_low_resolution);
5472 EXPECT_EQ(sender.qp_sum, 2u * *substream.qp_sum);
5473 EXPECT_EQ(sender.content_type, webrtc::VideoContentType::SCREENSHARE);
5474 EXPECT_EQ(sender.frames_sent, 2u * substream.frames_encoded);
5475 EXPECT_EQ(sender.huge_frames_sent, stats.huge_frames_sent);
5476 EXPECT_EQ(sender.rid, absl::nullopt);
5477 }
5478
TEST_F(WebRtcVideoChannelTest,GetPerLayerStatsReportForSubStreams)5479 TEST_F(WebRtcVideoChannelTest, GetPerLayerStatsReportForSubStreams) {
5480 FakeVideoSendStream* stream = AddSendStream();
5481 auto stats = GetInitialisedStats();
5482
5483 const uint32_t ssrc_1 = 123u;
5484 const uint32_t ssrc_2 = 456u;
5485
5486 auto& substream = stats.substreams[ssrc_1];
5487 substream.frame_counts.key_frames = 1;
5488 substream.frame_counts.delta_frames = 2;
5489 substream.width = 3;
5490 substream.height = 4;
5491 substream.total_bitrate_bps = 5;
5492 substream.retransmit_bitrate_bps = 6;
5493 substream.avg_delay_ms = 7;
5494 substream.max_delay_ms = 8;
5495 substream.total_packet_send_delay_ms = 9;
5496 substream.rtp_stats.transmitted.header_bytes = 10;
5497 substream.rtp_stats.transmitted.padding_bytes = 11;
5498 substream.rtp_stats.retransmitted.payload_bytes = 12;
5499 substream.rtp_stats.retransmitted.packets = 13;
5500 substream.rtcp_packet_type_counts.fir_packets = 14;
5501 substream.rtcp_packet_type_counts.nack_packets = 15;
5502 substream.rtcp_packet_type_counts.pli_packets = 16;
5503 substream.rtcp_stats.packets_lost = 17;
5504 substream.rtcp_stats.fraction_lost = 18;
5505 webrtc::ReportBlockData report_block_data;
5506 report_block_data.AddRoundTripTimeSample(19);
5507 substream.report_block_data = report_block_data;
5508 substream.encode_frame_rate = 20.0;
5509 substream.frames_encoded = 21;
5510 substream.qp_sum = 22;
5511 substream.total_encode_time_ms = 23;
5512 substream.total_encoded_bytes_target = 24;
5513 substream.huge_frames_sent = 25;
5514
5515 stats.substreams[ssrc_2] = substream;
5516
5517 stream->SetStats(stats);
5518
5519 cricket::VideoMediaInfo video_media_info;
5520 ASSERT_TRUE(channel_->GetStats(&video_media_info));
5521 EXPECT_EQ(video_media_info.senders.size(), 2u);
5522 auto& sender = video_media_info.senders[0];
5523
5524 // MediaSenderInfo
5525
5526 EXPECT_EQ(
5527 sender.payload_bytes_sent,
5528 static_cast<int64_t>(substream.rtp_stats.transmitted.payload_bytes));
5529 EXPECT_EQ(
5530 sender.header_and_padding_bytes_sent,
5531 static_cast<int64_t>(substream.rtp_stats.transmitted.header_bytes +
5532 substream.rtp_stats.transmitted.padding_bytes));
5533 EXPECT_EQ(sender.retransmitted_bytes_sent,
5534 substream.rtp_stats.retransmitted.payload_bytes);
5535 EXPECT_EQ(sender.packets_sent,
5536 static_cast<int>(substream.rtp_stats.transmitted.packets));
5537 EXPECT_EQ(sender.retransmitted_packets_sent,
5538 substream.rtp_stats.retransmitted.packets);
5539 EXPECT_EQ(sender.packets_lost, substream.rtcp_stats.packets_lost);
5540 EXPECT_EQ(sender.fraction_lost,
5541 static_cast<float>(substream.rtcp_stats.fraction_lost) / (1 << 8));
5542 EXPECT_EQ(sender.rtt_ms, 0);
5543 EXPECT_EQ(sender.codec_name, DefaultCodec().name);
5544 EXPECT_EQ(sender.codec_payload_type, DefaultCodec().id);
5545 EXPECT_EQ(sender.local_stats.size(), 1u);
5546 EXPECT_EQ(sender.local_stats[0].ssrc, ssrc_1);
5547 EXPECT_EQ(sender.local_stats[0].timestamp, 0.0f);
5548 EXPECT_EQ(sender.remote_stats.size(), 0u);
5549 EXPECT_EQ(sender.report_block_datas.size(), 1u);
5550
5551 // VideoSenderInfo
5552
5553 EXPECT_EQ(sender.ssrc_groups.size(), 0u);
5554 EXPECT_EQ(sender.encoder_implementation_name,
5555 stats.encoder_implementation_name);
5556 EXPECT_EQ(sender.firs_rcvd,
5557 static_cast<int>(substream.rtcp_packet_type_counts.fir_packets));
5558 EXPECT_EQ(sender.plis_rcvd,
5559 static_cast<int>(substream.rtcp_packet_type_counts.pli_packets));
5560 EXPECT_EQ(sender.nacks_rcvd,
5561 static_cast<int>(substream.rtcp_packet_type_counts.nack_packets));
5562 EXPECT_EQ(sender.send_frame_width, substream.width);
5563 EXPECT_EQ(sender.send_frame_height, substream.height);
5564
5565 EXPECT_EQ(sender.framerate_input, stats.input_frame_rate);
5566 EXPECT_EQ(sender.framerate_sent, substream.encode_frame_rate);
5567 EXPECT_EQ(sender.nominal_bitrate, stats.media_bitrate_bps);
5568 EXPECT_NE(sender.adapt_reason & WebRtcVideoChannel::ADAPTREASON_CPU, 0);
5569 EXPECT_NE(sender.adapt_reason & WebRtcVideoChannel::ADAPTREASON_BANDWIDTH, 0);
5570 EXPECT_EQ(sender.adapt_changes, stats.number_of_cpu_adapt_changes);
5571 EXPECT_EQ(sender.quality_limitation_reason, stats.quality_limitation_reason);
5572 EXPECT_EQ(sender.quality_limitation_durations_ms,
5573 stats.quality_limitation_durations_ms);
5574 EXPECT_EQ(sender.quality_limitation_resolution_changes,
5575 stats.quality_limitation_resolution_changes);
5576 EXPECT_EQ(sender.avg_encode_ms, stats.avg_encode_time_ms);
5577 EXPECT_EQ(sender.encode_usage_percent, stats.encode_usage_percent);
5578 EXPECT_EQ(sender.frames_encoded,
5579 static_cast<uint32_t>(substream.frames_encoded));
5580 EXPECT_EQ(sender.key_frames_encoded,
5581 static_cast<uint32_t>(substream.frame_counts.key_frames));
5582 EXPECT_EQ(sender.total_encode_time_ms, substream.total_encode_time_ms);
5583 EXPECT_EQ(sender.total_encoded_bytes_target,
5584 substream.total_encoded_bytes_target);
5585 EXPECT_EQ(sender.total_packet_send_delay_ms,
5586 substream.total_packet_send_delay_ms);
5587 EXPECT_EQ(sender.has_entered_low_resolution,
5588 stats.has_entered_low_resolution);
5589 EXPECT_EQ(sender.qp_sum, *substream.qp_sum);
5590 EXPECT_EQ(sender.content_type, webrtc::VideoContentType::SCREENSHARE);
5591 EXPECT_EQ(sender.frames_sent,
5592 static_cast<uint32_t>(substream.frames_encoded));
5593 EXPECT_EQ(sender.huge_frames_sent, substream.huge_frames_sent);
5594 EXPECT_EQ(sender.rid, absl::nullopt);
5595 }
5596
TEST_F(WebRtcVideoChannelTest,MediaSubstreamMissingProducesEmpyStats)5597 TEST_F(WebRtcVideoChannelTest, MediaSubstreamMissingProducesEmpyStats) {
5598 FakeVideoSendStream* stream = AddSendStream();
5599
5600 const uint32_t kRtxSsrc = 123u;
5601 const uint32_t kMissingMediaSsrc = 124u;
5602
5603 // Set up a scenarios where we have a substream that is not kMedia (in this
5604 // case: kRtx) but its associated kMedia stream does not exist yet. This
5605 // results in zero GetPerLayerVideoSenderInfos despite non-empty substreams.
5606 // Covers https://crbug.com/1090712.
5607 auto stats = GetInitialisedStats();
5608 auto& substream = stats.substreams[kRtxSsrc];
5609 substream.type = webrtc::VideoSendStream::StreamStats::StreamType::kRtx;
5610 substream.referenced_media_ssrc = kMissingMediaSsrc;
5611 stream->SetStats(stats);
5612
5613 cricket::VideoMediaInfo video_media_info;
5614 ASSERT_TRUE(channel_->GetStats(&video_media_info));
5615 EXPECT_TRUE(video_media_info.senders.empty());
5616 }
5617
TEST_F(WebRtcVideoChannelTest,GetStatsReportsUpperResolution)5618 TEST_F(WebRtcVideoChannelTest, GetStatsReportsUpperResolution) {
5619 FakeVideoSendStream* stream = AddSendStream();
5620 webrtc::VideoSendStream::Stats stats;
5621 stats.substreams[17].width = 123;
5622 stats.substreams[17].height = 40;
5623 stats.substreams[42].width = 80;
5624 stats.substreams[42].height = 31;
5625 stats.substreams[11].width = 20;
5626 stats.substreams[11].height = 90;
5627 stream->SetStats(stats);
5628
5629 cricket::VideoMediaInfo info;
5630 ASSERT_TRUE(channel_->GetStats(&info));
5631 ASSERT_EQ(1u, info.aggregated_senders.size());
5632 ASSERT_EQ(3u, info.senders.size());
5633 EXPECT_EQ(123, info.senders[1].send_frame_width);
5634 EXPECT_EQ(40, info.senders[1].send_frame_height);
5635 EXPECT_EQ(80, info.senders[2].send_frame_width);
5636 EXPECT_EQ(31, info.senders[2].send_frame_height);
5637 EXPECT_EQ(20, info.senders[0].send_frame_width);
5638 EXPECT_EQ(90, info.senders[0].send_frame_height);
5639 EXPECT_EQ(123, info.aggregated_senders[0].send_frame_width);
5640 EXPECT_EQ(90, info.aggregated_senders[0].send_frame_height);
5641 }
5642
TEST_F(WebRtcVideoChannelTest,GetStatsReportsCpuAdaptationStats)5643 TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuAdaptationStats) {
5644 FakeVideoSendStream* stream = AddSendStream();
5645 webrtc::VideoSendStream::Stats stats;
5646 stats.number_of_cpu_adapt_changes = 2;
5647 stats.cpu_limited_resolution = true;
5648 stream->SetStats(stats);
5649
5650 cricket::VideoMediaInfo info;
5651 EXPECT_TRUE(channel_->GetStats(&info));
5652 ASSERT_EQ(1U, info.senders.size());
5653 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU, info.senders[0].adapt_reason);
5654 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
5655 }
5656
TEST_F(WebRtcVideoChannelTest,GetStatsReportsAdaptationAndBandwidthStats)5657 TEST_F(WebRtcVideoChannelTest, GetStatsReportsAdaptationAndBandwidthStats) {
5658 FakeVideoSendStream* stream = AddSendStream();
5659 webrtc::VideoSendStream::Stats stats;
5660 stats.number_of_cpu_adapt_changes = 2;
5661 stats.cpu_limited_resolution = true;
5662 stats.bw_limited_resolution = true;
5663 stream->SetStats(stats);
5664
5665 cricket::VideoMediaInfo info;
5666 EXPECT_TRUE(channel_->GetStats(&info));
5667 ASSERT_EQ(1U, info.senders.size());
5668 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU |
5669 WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
5670 info.senders[0].adapt_reason);
5671 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
5672 }
5673
TEST(WebRtcVideoChannelHelperTest,MergeInfoAboutOutboundRtpSubstreams)5674 TEST(WebRtcVideoChannelHelperTest, MergeInfoAboutOutboundRtpSubstreams) {
5675 const uint32_t kFirstMediaStreamSsrc = 10;
5676 const uint32_t kSecondMediaStreamSsrc = 20;
5677 const uint32_t kRtxSsrc = 30;
5678 const uint32_t kFlexfecSsrc = 40;
5679 std::map<uint32_t, webrtc::VideoSendStream::StreamStats> substreams;
5680 // First kMedia stream.
5681 substreams[kFirstMediaStreamSsrc].type =
5682 webrtc::VideoSendStream::StreamStats::StreamType::kMedia;
5683 substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted.header_bytes = 1;
5684 substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted.padding_bytes = 2;
5685 substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted.payload_bytes = 3;
5686 substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted.packets = 4;
5687 substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.header_bytes = 5;
5688 substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.padding_bytes = 6;
5689 substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.payload_bytes = 7;
5690 substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.packets = 8;
5691 substreams[kFirstMediaStreamSsrc].referenced_media_ssrc = absl::nullopt;
5692 substreams[kFirstMediaStreamSsrc].width = 1280;
5693 substreams[kFirstMediaStreamSsrc].height = 720;
5694 // Second kMedia stream.
5695 substreams[kSecondMediaStreamSsrc].type =
5696 webrtc::VideoSendStream::StreamStats::StreamType::kMedia;
5697 substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted.header_bytes = 10;
5698 substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted.padding_bytes = 11;
5699 substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted.payload_bytes = 12;
5700 substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted.packets = 13;
5701 substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.header_bytes = 14;
5702 substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.padding_bytes = 15;
5703 substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.payload_bytes = 16;
5704 substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.packets = 17;
5705 substreams[kSecondMediaStreamSsrc].referenced_media_ssrc = absl::nullopt;
5706 substreams[kSecondMediaStreamSsrc].width = 640;
5707 substreams[kSecondMediaStreamSsrc].height = 480;
5708 // kRtx stream referencing the first kMedia stream.
5709 substreams[kRtxSsrc].type =
5710 webrtc::VideoSendStream::StreamStats::StreamType::kRtx;
5711 substreams[kRtxSsrc].rtp_stats.transmitted.header_bytes = 19;
5712 substreams[kRtxSsrc].rtp_stats.transmitted.padding_bytes = 20;
5713 substreams[kRtxSsrc].rtp_stats.transmitted.payload_bytes = 21;
5714 substreams[kRtxSsrc].rtp_stats.transmitted.packets = 22;
5715 substreams[kRtxSsrc].rtp_stats.retransmitted.header_bytes = 23;
5716 substreams[kRtxSsrc].rtp_stats.retransmitted.padding_bytes = 24;
5717 substreams[kRtxSsrc].rtp_stats.retransmitted.payload_bytes = 25;
5718 substreams[kRtxSsrc].rtp_stats.retransmitted.packets = 26;
5719 substreams[kRtxSsrc].referenced_media_ssrc = kFirstMediaStreamSsrc;
5720 // kFlexfec stream referencing the second kMedia stream.
5721 substreams[kFlexfecSsrc].type =
5722 webrtc::VideoSendStream::StreamStats::StreamType::kFlexfec;
5723 substreams[kFlexfecSsrc].rtp_stats.transmitted.header_bytes = 19;
5724 substreams[kFlexfecSsrc].rtp_stats.transmitted.padding_bytes = 20;
5725 substreams[kFlexfecSsrc].rtp_stats.transmitted.payload_bytes = 21;
5726 substreams[kFlexfecSsrc].rtp_stats.transmitted.packets = 22;
5727 substreams[kFlexfecSsrc].rtp_stats.retransmitted.header_bytes = 23;
5728 substreams[kFlexfecSsrc].rtp_stats.retransmitted.padding_bytes = 24;
5729 substreams[kFlexfecSsrc].rtp_stats.retransmitted.payload_bytes = 25;
5730 substreams[kFlexfecSsrc].rtp_stats.retransmitted.packets = 26;
5731 substreams[kFlexfecSsrc].referenced_media_ssrc = kSecondMediaStreamSsrc;
5732
5733 auto merged_substreams =
5734 MergeInfoAboutOutboundRtpSubstreamsForTesting(substreams);
5735 // Only kMedia substreams remain.
5736 EXPECT_TRUE(merged_substreams.find(kFirstMediaStreamSsrc) !=
5737 merged_substreams.end());
5738 EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].type,
5739 webrtc::VideoSendStream::StreamStats::StreamType::kMedia);
5740 EXPECT_TRUE(merged_substreams.find(kSecondMediaStreamSsrc) !=
5741 merged_substreams.end());
5742 EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].type,
5743 webrtc::VideoSendStream::StreamStats::StreamType::kMedia);
5744 EXPECT_FALSE(merged_substreams.find(kRtxSsrc) != merged_substreams.end());
5745 EXPECT_FALSE(merged_substreams.find(kFlexfecSsrc) != merged_substreams.end());
5746 // Expect kFirstMediaStreamSsrc's rtp_stats to be merged with kRtxSsrc.
5747 webrtc::StreamDataCounters first_media_expected_rtp_stats =
5748 substreams[kFirstMediaStreamSsrc].rtp_stats;
5749 first_media_expected_rtp_stats.Add(substreams[kRtxSsrc].rtp_stats);
5750 EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted,
5751 first_media_expected_rtp_stats.transmitted);
5752 EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted,
5753 first_media_expected_rtp_stats.retransmitted);
5754 // Expect kSecondMediaStreamSsrc' rtp_stats to be merged with kFlexfecSsrc.
5755 webrtc::StreamDataCounters second_media_expected_rtp_stats =
5756 substreams[kSecondMediaStreamSsrc].rtp_stats;
5757 second_media_expected_rtp_stats.Add(substreams[kFlexfecSsrc].rtp_stats);
5758 EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted,
5759 second_media_expected_rtp_stats.transmitted);
5760 EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted,
5761 second_media_expected_rtp_stats.retransmitted);
5762 // Expect other metrics to come from the original kMedia stats.
5763 EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].width,
5764 substreams[kFirstMediaStreamSsrc].width);
5765 EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].height,
5766 substreams[kFirstMediaStreamSsrc].height);
5767 EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].width,
5768 substreams[kSecondMediaStreamSsrc].width);
5769 EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].height,
5770 substreams[kSecondMediaStreamSsrc].height);
5771 }
5772
TEST_F(WebRtcVideoChannelTest,GetStatsReportsTransmittedAndRetransmittedBytesAndPacketsCorrectly)5773 TEST_F(WebRtcVideoChannelTest,
5774 GetStatsReportsTransmittedAndRetransmittedBytesAndPacketsCorrectly) {
5775 FakeVideoSendStream* stream = AddSendStream();
5776 webrtc::VideoSendStream::Stats stats;
5777 // Simulcast layer 1, RTP stream. header+padding=10, payload=20, packets=3.
5778 stats.substreams[101].type =
5779 webrtc::VideoSendStream::StreamStats::StreamType::kMedia;
5780 stats.substreams[101].rtp_stats.transmitted.header_bytes = 5;
5781 stats.substreams[101].rtp_stats.transmitted.padding_bytes = 5;
5782 stats.substreams[101].rtp_stats.transmitted.payload_bytes = 20;
5783 stats.substreams[101].rtp_stats.transmitted.packets = 3;
5784 stats.substreams[101].rtp_stats.retransmitted.header_bytes = 0;
5785 stats.substreams[101].rtp_stats.retransmitted.padding_bytes = 0;
5786 stats.substreams[101].rtp_stats.retransmitted.payload_bytes = 0;
5787 stats.substreams[101].rtp_stats.retransmitted.packets = 0;
5788 stats.substreams[101].referenced_media_ssrc = absl::nullopt;
5789 // Simulcast layer 1, RTX stream. header+padding=5, payload=10, packets=1.
5790 stats.substreams[102].type =
5791 webrtc::VideoSendStream::StreamStats::StreamType::kRtx;
5792 stats.substreams[102].rtp_stats.retransmitted.header_bytes = 3;
5793 stats.substreams[102].rtp_stats.retransmitted.padding_bytes = 2;
5794 stats.substreams[102].rtp_stats.retransmitted.payload_bytes = 10;
5795 stats.substreams[102].rtp_stats.retransmitted.packets = 1;
5796 stats.substreams[102].rtp_stats.transmitted =
5797 stats.substreams[102].rtp_stats.retransmitted;
5798 stats.substreams[102].referenced_media_ssrc = 101;
5799 // Simulcast layer 2, RTP stream. header+padding=20, payload=40, packets=7.
5800 stats.substreams[201].type =
5801 webrtc::VideoSendStream::StreamStats::StreamType::kMedia;
5802 stats.substreams[201].rtp_stats.transmitted.header_bytes = 10;
5803 stats.substreams[201].rtp_stats.transmitted.padding_bytes = 10;
5804 stats.substreams[201].rtp_stats.transmitted.payload_bytes = 40;
5805 stats.substreams[201].rtp_stats.transmitted.packets = 7;
5806 stats.substreams[201].rtp_stats.retransmitted.header_bytes = 0;
5807 stats.substreams[201].rtp_stats.retransmitted.padding_bytes = 0;
5808 stats.substreams[201].rtp_stats.retransmitted.payload_bytes = 0;
5809 stats.substreams[201].rtp_stats.retransmitted.packets = 0;
5810 stats.substreams[201].referenced_media_ssrc = absl::nullopt;
5811 // Simulcast layer 2, RTX stream. header+padding=10, payload=20, packets=4.
5812 stats.substreams[202].type =
5813 webrtc::VideoSendStream::StreamStats::StreamType::kRtx;
5814 stats.substreams[202].rtp_stats.retransmitted.header_bytes = 6;
5815 stats.substreams[202].rtp_stats.retransmitted.padding_bytes = 4;
5816 stats.substreams[202].rtp_stats.retransmitted.payload_bytes = 20;
5817 stats.substreams[202].rtp_stats.retransmitted.packets = 4;
5818 stats.substreams[202].rtp_stats.transmitted =
5819 stats.substreams[202].rtp_stats.retransmitted;
5820 stats.substreams[202].referenced_media_ssrc = 201;
5821 // FlexFEC stream associated with the Simulcast layer 2.
5822 // header+padding=15, payload=17, packets=5.
5823 stats.substreams[301].type =
5824 webrtc::VideoSendStream::StreamStats::StreamType::kFlexfec;
5825 stats.substreams[301].rtp_stats.transmitted.header_bytes = 13;
5826 stats.substreams[301].rtp_stats.transmitted.padding_bytes = 2;
5827 stats.substreams[301].rtp_stats.transmitted.payload_bytes = 17;
5828 stats.substreams[301].rtp_stats.transmitted.packets = 5;
5829 stats.substreams[301].rtp_stats.retransmitted.header_bytes = 0;
5830 stats.substreams[301].rtp_stats.retransmitted.padding_bytes = 0;
5831 stats.substreams[301].rtp_stats.retransmitted.payload_bytes = 0;
5832 stats.substreams[301].rtp_stats.retransmitted.packets = 0;
5833 stats.substreams[301].referenced_media_ssrc = 201;
5834 stream->SetStats(stats);
5835
5836 cricket::VideoMediaInfo info;
5837 ASSERT_TRUE(channel_->GetStats(&info));
5838 EXPECT_EQ(info.senders.size(), 2u);
5839 EXPECT_EQ(15u, info.senders[0].header_and_padding_bytes_sent);
5840 EXPECT_EQ(30u, info.senders[0].payload_bytes_sent);
5841 EXPECT_EQ(4, info.senders[0].packets_sent);
5842 EXPECT_EQ(10u, info.senders[0].retransmitted_bytes_sent);
5843 EXPECT_EQ(1u, info.senders[0].retransmitted_packets_sent);
5844
5845 EXPECT_EQ(45u, info.senders[1].header_and_padding_bytes_sent);
5846 EXPECT_EQ(77u, info.senders[1].payload_bytes_sent);
5847 EXPECT_EQ(16, info.senders[1].packets_sent);
5848 EXPECT_EQ(20u, info.senders[1].retransmitted_bytes_sent);
5849 EXPECT_EQ(4u, info.senders[1].retransmitted_packets_sent);
5850 }
5851
TEST_F(WebRtcVideoChannelTest,GetStatsTranslatesBandwidthLimitedResolutionCorrectly)5852 TEST_F(WebRtcVideoChannelTest,
5853 GetStatsTranslatesBandwidthLimitedResolutionCorrectly) {
5854 FakeVideoSendStream* stream = AddSendStream();
5855 webrtc::VideoSendStream::Stats stats;
5856 stats.bw_limited_resolution = true;
5857 stream->SetStats(stats);
5858
5859 cricket::VideoMediaInfo info;
5860 EXPECT_TRUE(channel_->GetStats(&info));
5861 ASSERT_EQ(1U, info.senders.size());
5862 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
5863 info.senders[0].adapt_reason);
5864 }
5865
TEST_F(WebRtcVideoChannelTest,GetStatsTranslatesSendRtcpPacketTypesCorrectly)5866 TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesSendRtcpPacketTypesCorrectly) {
5867 FakeVideoSendStream* stream = AddSendStream();
5868 webrtc::VideoSendStream::Stats stats;
5869 stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2;
5870 stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3;
5871 stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4;
5872
5873 stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5;
5874 stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7;
5875 stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9;
5876
5877 stream->SetStats(stats);
5878
5879 cricket::VideoMediaInfo info;
5880 ASSERT_TRUE(channel_->GetStats(&info));
5881 EXPECT_EQ(2, info.senders[0].firs_rcvd);
5882 EXPECT_EQ(3, info.senders[0].nacks_rcvd);
5883 EXPECT_EQ(4, info.senders[0].plis_rcvd);
5884
5885 EXPECT_EQ(5, info.senders[1].firs_rcvd);
5886 EXPECT_EQ(7, info.senders[1].nacks_rcvd);
5887 EXPECT_EQ(9, info.senders[1].plis_rcvd);
5888
5889 EXPECT_EQ(7, info.aggregated_senders[0].firs_rcvd);
5890 EXPECT_EQ(10, info.aggregated_senders[0].nacks_rcvd);
5891 EXPECT_EQ(13, info.aggregated_senders[0].plis_rcvd);
5892 }
5893
TEST_F(WebRtcVideoChannelTest,GetStatsTranslatesReceiveRtcpPacketTypesCorrectly)5894 TEST_F(WebRtcVideoChannelTest,
5895 GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) {
5896 FakeVideoReceiveStream* stream = AddRecvStream();
5897 webrtc::VideoReceiveStream::Stats stats;
5898 stats.rtcp_packet_type_counts.fir_packets = 2;
5899 stats.rtcp_packet_type_counts.nack_packets = 3;
5900 stats.rtcp_packet_type_counts.pli_packets = 4;
5901 stream->SetStats(stats);
5902
5903 cricket::VideoMediaInfo info;
5904 ASSERT_TRUE(channel_->GetStats(&info));
5905 EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets,
5906 rtc::checked_cast<unsigned int>(info.receivers[0].firs_sent));
5907 EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets,
5908 rtc::checked_cast<unsigned int>(info.receivers[0].nacks_sent));
5909 EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets,
5910 rtc::checked_cast<unsigned int>(info.receivers[0].plis_sent));
5911 }
5912
TEST_F(WebRtcVideoChannelTest,GetStatsTranslatesDecodeStatsCorrectly)5913 TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesDecodeStatsCorrectly) {
5914 FakeVideoReceiveStream* stream = AddRecvStream();
5915 webrtc::VideoReceiveStream::Stats stats;
5916 stats.decoder_implementation_name = "decoder_implementation_name";
5917 stats.decode_ms = 2;
5918 stats.max_decode_ms = 3;
5919 stats.current_delay_ms = 4;
5920 stats.target_delay_ms = 5;
5921 stats.jitter_buffer_ms = 6;
5922 stats.jitter_buffer_delay_seconds = 60;
5923 stats.jitter_buffer_emitted_count = 6;
5924 stats.min_playout_delay_ms = 7;
5925 stats.render_delay_ms = 8;
5926 stats.width = 9;
5927 stats.height = 10;
5928 stats.frame_counts.key_frames = 11;
5929 stats.frame_counts.delta_frames = 12;
5930 stats.frames_rendered = 13;
5931 stats.frames_decoded = 14;
5932 stats.qp_sum = 15;
5933 stats.total_decode_time_ms = 16;
5934 stream->SetStats(stats);
5935
5936 cricket::VideoMediaInfo info;
5937 ASSERT_TRUE(channel_->GetStats(&info));
5938 EXPECT_EQ(stats.decoder_implementation_name,
5939 info.receivers[0].decoder_implementation_name);
5940 EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
5941 EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
5942 EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
5943 EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
5944 EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
5945 EXPECT_EQ(stats.jitter_buffer_delay_seconds,
5946 info.receivers[0].jitter_buffer_delay_seconds);
5947 EXPECT_EQ(stats.jitter_buffer_emitted_count,
5948 info.receivers[0].jitter_buffer_emitted_count);
5949 EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
5950 EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
5951 EXPECT_EQ(stats.width, info.receivers[0].frame_width);
5952 EXPECT_EQ(stats.height, info.receivers[0].frame_height);
5953 EXPECT_EQ(rtc::checked_cast<unsigned int>(stats.frame_counts.key_frames +
5954 stats.frame_counts.delta_frames),
5955 info.receivers[0].frames_received);
5956 EXPECT_EQ(stats.frames_rendered, info.receivers[0].frames_rendered);
5957 EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded);
5958 EXPECT_EQ(rtc::checked_cast<unsigned int>(stats.frame_counts.key_frames),
5959 info.receivers[0].key_frames_decoded);
5960 EXPECT_EQ(stats.qp_sum, info.receivers[0].qp_sum);
5961 EXPECT_EQ(stats.total_decode_time_ms, info.receivers[0].total_decode_time_ms);
5962 }
5963
TEST_F(WebRtcVideoChannelTest,GetStatsTranslatesInterFrameDelayStatsCorrectly)5964 TEST_F(WebRtcVideoChannelTest,
5965 GetStatsTranslatesInterFrameDelayStatsCorrectly) {
5966 FakeVideoReceiveStream* stream = AddRecvStream();
5967 webrtc::VideoReceiveStream::Stats stats;
5968 stats.total_inter_frame_delay = 0.123;
5969 stats.total_squared_inter_frame_delay = 0.00456;
5970 stream->SetStats(stats);
5971
5972 cricket::VideoMediaInfo info;
5973 ASSERT_TRUE(channel_->GetStats(&info));
5974 EXPECT_EQ(stats.total_inter_frame_delay,
5975 info.receivers[0].total_inter_frame_delay);
5976 EXPECT_EQ(stats.total_squared_inter_frame_delay,
5977 info.receivers[0].total_squared_inter_frame_delay);
5978 }
5979
TEST_F(WebRtcVideoChannelTest,GetStatsTranslatesReceivePacketStatsCorrectly)5980 TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesReceivePacketStatsCorrectly) {
5981 FakeVideoReceiveStream* stream = AddRecvStream();
5982 webrtc::VideoReceiveStream::Stats stats;
5983 stats.rtp_stats.packet_counter.payload_bytes = 2;
5984 stats.rtp_stats.packet_counter.header_bytes = 3;
5985 stats.rtp_stats.packet_counter.padding_bytes = 4;
5986 stats.rtp_stats.packet_counter.packets = 5;
5987 stats.rtp_stats.packets_lost = 6;
5988 stream->SetStats(stats);
5989
5990 cricket::VideoMediaInfo info;
5991 ASSERT_TRUE(channel_->GetStats(&info));
5992 EXPECT_EQ(stats.rtp_stats.packet_counter.payload_bytes,
5993 rtc::checked_cast<size_t>(info.receivers[0].payload_bytes_rcvd));
5994 EXPECT_EQ(stats.rtp_stats.packet_counter.packets,
5995 rtc::checked_cast<unsigned int>(info.receivers[0].packets_rcvd));
5996 EXPECT_EQ(stats.rtp_stats.packets_lost, info.receivers[0].packets_lost);
5997 }
5998
TEST_F(WebRtcVideoChannelTest,TranslatesCallStatsCorrectly)5999 TEST_F(WebRtcVideoChannelTest, TranslatesCallStatsCorrectly) {
6000 AddSendStream();
6001 AddSendStream();
6002 webrtc::Call::Stats stats;
6003 stats.rtt_ms = 123;
6004 fake_call_->SetStats(stats);
6005
6006 cricket::VideoMediaInfo info;
6007 ASSERT_TRUE(channel_->GetStats(&info));
6008 ASSERT_EQ(2u, info.senders.size());
6009 EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms);
6010 EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
6011 }
6012
TEST_F(WebRtcVideoChannelTest,TranslatesSenderBitrateStatsCorrectly)6013 TEST_F(WebRtcVideoChannelTest, TranslatesSenderBitrateStatsCorrectly) {
6014 FakeVideoSendStream* stream = AddSendStream();
6015 webrtc::VideoSendStream::Stats stats;
6016 stats.target_media_bitrate_bps = 156;
6017 stats.media_bitrate_bps = 123;
6018 stats.substreams[17].total_bitrate_bps = 1;
6019 stats.substreams[17].retransmit_bitrate_bps = 2;
6020 stats.substreams[42].total_bitrate_bps = 3;
6021 stats.substreams[42].retransmit_bitrate_bps = 4;
6022 stream->SetStats(stats);
6023
6024 FakeVideoSendStream* stream2 = AddSendStream();
6025 webrtc::VideoSendStream::Stats stats2;
6026 stats2.target_media_bitrate_bps = 200;
6027 stats2.media_bitrate_bps = 321;
6028 stats2.substreams[13].total_bitrate_bps = 5;
6029 stats2.substreams[13].retransmit_bitrate_bps = 6;
6030 stats2.substreams[21].total_bitrate_bps = 7;
6031 stats2.substreams[21].retransmit_bitrate_bps = 8;
6032 stream2->SetStats(stats2);
6033
6034 cricket::VideoMediaInfo info;
6035 ASSERT_TRUE(channel_->GetStats(&info));
6036 ASSERT_EQ(2u, info.aggregated_senders.size());
6037 ASSERT_EQ(4u, info.senders.size());
6038 BandwidthEstimationInfo bwe_info;
6039 channel_->FillBitrateInfo(&bwe_info);
6040 // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
6041 // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
6042 EXPECT_EQ(stats.media_bitrate_bps,
6043 info.aggregated_senders[0].nominal_bitrate);
6044 EXPECT_EQ(stats2.media_bitrate_bps,
6045 info.aggregated_senders[1].nominal_bitrate);
6046 EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
6047 bwe_info.target_enc_bitrate);
6048 EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
6049 bwe_info.actual_enc_bitrate);
6050 EXPECT_EQ(1 + 3 + 5 + 7, bwe_info.transmit_bitrate)
6051 << "Bandwidth stats should take all streams into account.";
6052 EXPECT_EQ(2 + 4 + 6 + 8, bwe_info.retransmit_bitrate)
6053 << "Bandwidth stats should take all streams into account.";
6054 }
6055
TEST_F(WebRtcVideoChannelTest,DefaultReceiveStreamReconfiguresToUseRtx)6056 TEST_F(WebRtcVideoChannelTest, DefaultReceiveStreamReconfiguresToUseRtx) {
6057 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
6058
6059 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
6060 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
6061
6062 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
6063 const size_t kDataLength = 12;
6064 uint8_t data[kDataLength];
6065 memset(data, 0, sizeof(data));
6066 rtc::SetBE32(&data[8], ssrcs[0]);
6067 rtc::CopyOnWriteBuffer packet(data, kDataLength);
6068 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
6069
6070 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
6071 << "No default receive stream created.";
6072 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
6073 EXPECT_EQ(0u, recv_stream->GetConfig().rtp.rtx_ssrc)
6074 << "Default receive stream should not have configured RTX";
6075
6076 EXPECT_TRUE(channel_->AddRecvStream(
6077 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
6078 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
6079 << "AddRecvStream should have reconfigured, not added a new receiver.";
6080 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
6081 EXPECT_FALSE(
6082 recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
6083 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
6084 << "RTX should be mapped for all decoders/payload types.";
6085 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
6086 GetEngineCodec("red").id))
6087 << "RTX should be mapped also for the RED payload type";
6088 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
6089 }
6090
TEST_F(WebRtcVideoChannelTest,RejectsAddingStreamsWithMissingSsrcsForRtx)6091 TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithMissingSsrcsForRtx) {
6092 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
6093
6094 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
6095 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
6096
6097 StreamParams sp =
6098 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
6099 sp.ssrcs = ssrcs; // Without RTXs, this is the important part.
6100
6101 EXPECT_FALSE(channel_->AddSendStream(sp));
6102 EXPECT_FALSE(channel_->AddRecvStream(sp));
6103 }
6104
TEST_F(WebRtcVideoChannelTest,RejectsAddingStreamsWithOverlappingRtxSsrcs)6105 TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithOverlappingRtxSsrcs) {
6106 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
6107
6108 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
6109 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
6110
6111 StreamParams sp =
6112 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
6113
6114 EXPECT_TRUE(channel_->AddSendStream(sp));
6115 EXPECT_TRUE(channel_->AddRecvStream(sp));
6116
6117 // The RTX SSRC is already used in previous streams, using it should fail.
6118 sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]);
6119 EXPECT_FALSE(channel_->AddSendStream(sp));
6120 EXPECT_FALSE(channel_->AddRecvStream(sp));
6121
6122 // After removing the original stream this should be fine to add (makes sure
6123 // that RTX ssrcs are not forever taken).
6124 EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0]));
6125 EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0]));
6126 EXPECT_TRUE(channel_->AddSendStream(sp));
6127 EXPECT_TRUE(channel_->AddRecvStream(sp));
6128 }
6129
TEST_F(WebRtcVideoChannelTest,RejectsAddingStreamsWithOverlappingSimulcastSsrcs)6130 TEST_F(WebRtcVideoChannelTest,
6131 RejectsAddingStreamsWithOverlappingSimulcastSsrcs) {
6132 static const uint32_t kFirstStreamSsrcs[] = {1, 2, 3};
6133 static const uint32_t kOverlappingStreamSsrcs[] = {4, 3, 5};
6134 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
6135
6136 StreamParams sp =
6137 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs));
6138
6139 EXPECT_TRUE(channel_->AddSendStream(sp));
6140 EXPECT_TRUE(channel_->AddRecvStream(sp));
6141
6142 // One of the SSRCs is already used in previous streams, using it should fail.
6143 sp = cricket::CreateSimStreamParams("cname",
6144 MAKE_VECTOR(kOverlappingStreamSsrcs));
6145 EXPECT_FALSE(channel_->AddSendStream(sp));
6146 EXPECT_FALSE(channel_->AddRecvStream(sp));
6147
6148 // After removing the original stream this should be fine to add (makes sure
6149 // that RTX ssrcs are not forever taken).
6150 EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0]));
6151 EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0]));
6152 EXPECT_TRUE(channel_->AddSendStream(sp));
6153 EXPECT_TRUE(channel_->AddRecvStream(sp));
6154 }
6155
TEST_F(WebRtcVideoChannelTest,ReportsSsrcGroupsInStats)6156 TEST_F(WebRtcVideoChannelTest, ReportsSsrcGroupsInStats) {
6157 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
6158
6159 static const uint32_t kSenderSsrcs[] = {4, 7, 10};
6160 static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11};
6161
6162 StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams(
6163 "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs));
6164
6165 EXPECT_TRUE(channel_->AddSendStream(sender_sp));
6166
6167 static const uint32_t kReceiverSsrcs[] = {3};
6168 static const uint32_t kReceiverRtxSsrcs[] = {2};
6169
6170 StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams(
6171 "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs));
6172 EXPECT_TRUE(channel_->AddRecvStream(receiver_sp));
6173
6174 cricket::VideoMediaInfo info;
6175 ASSERT_TRUE(channel_->GetStats(&info));
6176
6177 ASSERT_EQ(1u, info.senders.size());
6178 ASSERT_EQ(1u, info.receivers.size());
6179
6180 EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups);
6181 EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups);
6182 EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
6183 }
6184
TEST_F(WebRtcVideoChannelTest,MapsReceivedPayloadTypeToCodecName)6185 TEST_F(WebRtcVideoChannelTest, MapsReceivedPayloadTypeToCodecName) {
6186 FakeVideoReceiveStream* stream = AddRecvStream();
6187 webrtc::VideoReceiveStream::Stats stats;
6188 cricket::VideoMediaInfo info;
6189
6190 // Report no codec name before receiving.
6191 stream->SetStats(stats);
6192 ASSERT_TRUE(channel_->GetStats(&info));
6193 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
6194
6195 // Report VP8 if we're receiving it.
6196 stats.current_payload_type = GetEngineCodec("VP8").id;
6197 stream->SetStats(stats);
6198 ASSERT_TRUE(channel_->GetStats(&info));
6199 EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());
6200
6201 // Report no codec name for unknown playload types.
6202 stats.current_payload_type = 3;
6203 stream->SetStats(stats);
6204 ASSERT_TRUE(channel_->GetStats(&info));
6205 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
6206 }
6207
6208 // Tests that when we add a stream without SSRCs, but contains a stream_id
6209 // that it is stored and its stream id is later used when the first packet
6210 // arrives to properly create a receive stream with a sync label.
TEST_F(WebRtcVideoChannelTest,RecvUnsignaledSsrcWithSignaledStreamId)6211 TEST_F(WebRtcVideoChannelTest, RecvUnsignaledSsrcWithSignaledStreamId) {
6212 const char kSyncLabel[] = "sync_label";
6213 cricket::StreamParams unsignaled_stream;
6214 unsignaled_stream.set_stream_ids({kSyncLabel});
6215 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
6216 // The stream shouldn't have been created at this point because it doesn't
6217 // have any SSRCs.
6218 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
6219
6220 // Create and deliver packet.
6221 const size_t kDataLength = 12;
6222 uint8_t data[kDataLength];
6223 memset(data, 0, sizeof(data));
6224 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
6225 rtc::CopyOnWriteBuffer packet(data, kDataLength);
6226 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
6227
6228 // The stream should now be created with the appropriate sync label.
6229 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
6230 EXPECT_EQ(kSyncLabel,
6231 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group);
6232
6233 // Reset the unsignaled stream to clear the cache. This time when
6234 // a default video receive stream is created it won't have a sync_group.
6235 channel_->ResetUnsignaledRecvStream();
6236 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
6237
6238 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
6239 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
6240 EXPECT_TRUE(
6241 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group.empty());
6242 }
6243
TEST_F(WebRtcVideoChannelTest,ResetUnsignaledRecvStreamDeletesAllDefaultStreams)6244 TEST_F(WebRtcVideoChannelTest,
6245 ResetUnsignaledRecvStreamDeletesAllDefaultStreams) {
6246 // No receive streams to start with.
6247 EXPECT_TRUE(fake_call_->GetVideoReceiveStreams().empty());
6248
6249 // Packet with unsignaled SSRC is received.
6250 const size_t kDataLength = 12;
6251 uint8_t data[kDataLength];
6252 memset(data, 0, sizeof(data));
6253 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
6254 rtc::CopyOnWriteBuffer packet(data, kDataLength);
6255 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
6256
6257 // Default receive stream created.
6258 const auto& receivers1 = fake_call_->GetVideoReceiveStreams();
6259 ASSERT_EQ(receivers1.size(), 1u);
6260 EXPECT_EQ(receivers1[0]->GetConfig().rtp.remote_ssrc,
6261 kIncomingUnsignalledSsrc);
6262
6263 // Stream with another SSRC gets signaled.
6264 channel_->ResetUnsignaledRecvStream();
6265 constexpr uint32_t kIncomingSignalledSsrc = kIncomingUnsignalledSsrc + 1;
6266 ASSERT_TRUE(channel_->AddRecvStream(
6267 cricket::StreamParams::CreateLegacy(kIncomingSignalledSsrc)));
6268
6269 // New receiver is for the signaled stream.
6270 const auto& receivers2 = fake_call_->GetVideoReceiveStreams();
6271 ASSERT_EQ(receivers2.size(), 1u);
6272 EXPECT_EQ(receivers2[0]->GetConfig().rtp.remote_ssrc, kIncomingSignalledSsrc);
6273 }
6274
6275 // Test BaseMinimumPlayoutDelayMs on receive streams.
TEST_F(WebRtcVideoChannelTest,BaseMinimumPlayoutDelayMs)6276 TEST_F(WebRtcVideoChannelTest, BaseMinimumPlayoutDelayMs) {
6277 // Test that set won't work for non-existing receive streams.
6278 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc + 2, 200));
6279 // Test that get won't work for non-existing receive streams.
6280 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrc + 2));
6281
6282 EXPECT_TRUE(AddRecvStream());
6283 // Test that set works for the existing receive stream.
6284 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(last_ssrc_, 200));
6285 auto* recv_stream = fake_call_->GetVideoReceiveStream(last_ssrc_);
6286 EXPECT_TRUE(recv_stream);
6287 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 200);
6288 EXPECT_EQ(channel_->GetBaseMinimumPlayoutDelayMs(last_ssrc_).value_or(0),
6289 200);
6290 }
6291
6292 // Test BaseMinimumPlayoutDelayMs on unsignaled receive streams.
TEST_F(WebRtcVideoChannelTest,BaseMinimumPlayoutDelayMsUnsignaledRecvStream)6293 TEST_F(WebRtcVideoChannelTest, BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
6294 absl::optional<int> delay_ms;
6295 const FakeVideoReceiveStream* recv_stream;
6296
6297 // Set default stream with SSRC 0
6298 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(0, 200));
6299 EXPECT_EQ(200, channel_->GetBaseMinimumPlayoutDelayMs(0).value_or(0));
6300
6301 // Spawn an unsignaled stream by sending a packet, it should inherit
6302 // default delay 200.
6303 const size_t kDataLength = 12;
6304 uint8_t data[kDataLength];
6305 memset(data, 0, sizeof(data));
6306 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
6307 rtc::CopyOnWriteBuffer packet(data, kDataLength);
6308 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
6309
6310 recv_stream = fake_call_->GetVideoReceiveStream(kIncomingUnsignalledSsrc);
6311 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 200);
6312 delay_ms = channel_->GetBaseMinimumPlayoutDelayMs(kIncomingUnsignalledSsrc);
6313 EXPECT_EQ(200, delay_ms.value_or(0));
6314
6315 // Check that now if we change delay for SSRC 0 it will change delay for the
6316 // default receiving stream as well.
6317 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(0, 300));
6318 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(0).value_or(0));
6319 delay_ms = channel_->GetBaseMinimumPlayoutDelayMs(kIncomingUnsignalledSsrc);
6320 EXPECT_EQ(300, delay_ms.value_or(0));
6321 recv_stream = fake_call_->GetVideoReceiveStream(kIncomingUnsignalledSsrc);
6322 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 300);
6323 }
6324
TestReceiveUnsignaledSsrcPacket(uint8_t payload_type,bool expect_created_receive_stream)6325 void WebRtcVideoChannelTest::TestReceiveUnsignaledSsrcPacket(
6326 uint8_t payload_type,
6327 bool expect_created_receive_stream) {
6328 // kRedRtxPayloadType must currently be unused.
6329 EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kRedRtxPayloadType));
6330
6331 // Add a RED RTX codec.
6332 VideoCodec red_rtx_codec =
6333 VideoCodec::CreateRtxCodec(kRedRtxPayloadType, GetEngineCodec("red").id);
6334 recv_parameters_.codecs.push_back(red_rtx_codec);
6335 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
6336
6337 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
6338 const size_t kDataLength = 12;
6339 uint8_t data[kDataLength];
6340 memset(data, 0, sizeof(data));
6341
6342 rtc::Set8(data, 1, payload_type);
6343 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
6344 rtc::CopyOnWriteBuffer packet(data, kDataLength);
6345 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
6346
6347 if (expect_created_receive_stream) {
6348 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
6349 << "Should have created a receive stream for payload type: "
6350 << payload_type;
6351 } else {
6352 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size())
6353 << "Shouldn't have created a receive stream for payload type: "
6354 << payload_type;
6355 }
6356 }
6357
6358 class WebRtcVideoChannelDiscardUnknownSsrcTest : public WebRtcVideoChannelTest {
6359 public:
WebRtcVideoChannelDiscardUnknownSsrcTest()6360 WebRtcVideoChannelDiscardUnknownSsrcTest()
6361 : WebRtcVideoChannelTest(
6362 "WebRTC-Video-DiscardPacketsWithUnknownSsrc/Enabled/") {}
6363 };
6364
TEST_F(WebRtcVideoChannelDiscardUnknownSsrcTest,NoUnsignalledStreamCreated)6365 TEST_F(WebRtcVideoChannelDiscardUnknownSsrcTest, NoUnsignalledStreamCreated) {
6366 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
6367 false /* expect_created_receive_stream */);
6368 }
6369
TEST_F(WebRtcVideoChannelTest,Vp8PacketCreatesUnsignalledStream)6370 TEST_F(WebRtcVideoChannelTest, Vp8PacketCreatesUnsignalledStream) {
6371 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
6372 true /* expect_created_receive_stream */);
6373 }
6374
TEST_F(WebRtcVideoChannelTest,Vp9PacketCreatesUnsignalledStream)6375 TEST_F(WebRtcVideoChannelTest, Vp9PacketCreatesUnsignalledStream) {
6376 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP9").id,
6377 true /* expect_created_receive_stream */);
6378 }
6379
TEST_F(WebRtcVideoChannelTest,RtxPacketDoesntCreateUnsignalledStream)6380 TEST_F(WebRtcVideoChannelTest, RtxPacketDoesntCreateUnsignalledStream) {
6381 AssignDefaultAptRtxTypes();
6382 const cricket::VideoCodec vp8 = GetEngineCodec("VP8");
6383 const int rtx_vp8_payload_type = default_apt_rtx_types_[vp8.id];
6384 TestReceiveUnsignaledSsrcPacket(rtx_vp8_payload_type,
6385 false /* expect_created_receive_stream */);
6386 }
6387
TEST_F(WebRtcVideoChannelTest,UlpfecPacketDoesntCreateUnsignalledStream)6388 TEST_F(WebRtcVideoChannelTest, UlpfecPacketDoesntCreateUnsignalledStream) {
6389 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("ulpfec").id,
6390 false /* expect_created_receive_stream */);
6391 }
6392
TEST_F(WebRtcVideoChannelFlexfecRecvTest,FlexfecPacketDoesntCreateUnsignalledStream)6393 TEST_F(WebRtcVideoChannelFlexfecRecvTest,
6394 FlexfecPacketDoesntCreateUnsignalledStream) {
6395 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("flexfec-03").id,
6396 false /* expect_created_receive_stream */);
6397 }
6398
TEST_F(WebRtcVideoChannelTest,RedRtxPacketDoesntCreateUnsignalledStream)6399 TEST_F(WebRtcVideoChannelTest, RedRtxPacketDoesntCreateUnsignalledStream) {
6400 TestReceiveUnsignaledSsrcPacket(kRedRtxPayloadType,
6401 false /* expect_created_receive_stream */);
6402 }
6403
6404 // Test that receiving any unsignalled SSRC works even if it changes.
6405 // The first unsignalled SSRC received will create a default receive stream.
6406 // Any different unsignalled SSRC received will replace the default.
TEST_F(WebRtcVideoChannelTest,ReceiveDifferentUnsignaledSsrc)6407 TEST_F(WebRtcVideoChannelTest, ReceiveDifferentUnsignaledSsrc) {
6408 // Allow receiving VP8, VP9, H264 (if enabled).
6409 cricket::VideoRecvParameters parameters;
6410 parameters.codecs.push_back(GetEngineCodec("VP8"));
6411 parameters.codecs.push_back(GetEngineCodec("VP9"));
6412
6413 #if defined(WEBRTC_USE_H264)
6414 cricket::VideoCodec H264codec(126, "H264");
6415 parameters.codecs.push_back(H264codec);
6416 #endif
6417
6418 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
6419 // No receive streams yet.
6420 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
6421 cricket::FakeVideoRenderer renderer;
6422 channel_->SetDefaultSink(&renderer);
6423
6424 // Receive VP8 packet on first SSRC.
6425 uint8_t data[kMinRtpPacketLen];
6426 cricket::RtpHeader rtpHeader;
6427 rtpHeader.payload_type = GetEngineCodec("VP8").id;
6428 rtpHeader.seq_num = rtpHeader.timestamp = 0;
6429 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 1;
6430 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
6431 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
6432 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
6433 // VP8 packet should create default receive stream.
6434 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
6435 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
6436 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
6437 // Verify that the receive stream sinks to a renderer.
6438 webrtc::VideoFrame video_frame =
6439 webrtc::VideoFrame::Builder()
6440 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
6441 .set_timestamp_rtp(100)
6442 .set_timestamp_us(0)
6443 .set_rotation(webrtc::kVideoRotation_0)
6444 .build();
6445 recv_stream->InjectFrame(video_frame);
6446 EXPECT_EQ(1, renderer.num_rendered_frames());
6447
6448 // Receive VP9 packet on second SSRC.
6449 rtpHeader.payload_type = GetEngineCodec("VP9").id;
6450 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 2;
6451 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
6452 rtc::CopyOnWriteBuffer packet2(data, sizeof(data));
6453 channel_->OnPacketReceived(packet2, /* packet_time_us */ -1);
6454 // VP9 packet should replace the default receive SSRC.
6455 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
6456 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
6457 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
6458 // Verify that the receive stream sinks to a renderer.
6459 webrtc::VideoFrame video_frame2 =
6460 webrtc::VideoFrame::Builder()
6461 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
6462 .set_timestamp_rtp(200)
6463 .set_timestamp_us(0)
6464 .set_rotation(webrtc::kVideoRotation_0)
6465 .build();
6466 recv_stream->InjectFrame(video_frame2);
6467 EXPECT_EQ(2, renderer.num_rendered_frames());
6468
6469 #if defined(WEBRTC_USE_H264)
6470 // Receive H264 packet on third SSRC.
6471 rtpHeader.payload_type = 126;
6472 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 3;
6473 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
6474 rtc::CopyOnWriteBuffer packet3(data, sizeof(data));
6475 channel_->OnPacketReceived(packet3, /* packet_time_us */ -1);
6476 // H264 packet should replace the default receive SSRC.
6477 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
6478 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
6479 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
6480 // Verify that the receive stream sinks to a renderer.
6481 webrtc::VideoFrame video_frame3 =
6482 webrtc::VideoFrame::Builder()
6483 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
6484 .set_timestamp_rtp(300)
6485 .set_timestamp_us(0)
6486 .set_rotation(webrtc::kVideoRotation_0)
6487 .build();
6488 recv_stream->InjectFrame(video_frame3);
6489 EXPECT_EQ(3, renderer.num_rendered_frames());
6490 #endif
6491 }
6492
6493 // This test verifies that when a new default stream is created for a new
6494 // unsignaled SSRC, the new stream does not overwrite any old stream that had
6495 // been the default receive stream before being properly signaled.
TEST_F(WebRtcVideoChannelTest,NewUnsignaledStreamDoesNotDestroyPreviouslyUnsignaledStream)6496 TEST_F(WebRtcVideoChannelTest,
6497 NewUnsignaledStreamDoesNotDestroyPreviouslyUnsignaledStream) {
6498 cricket::VideoRecvParameters parameters;
6499 parameters.codecs.push_back(GetEngineCodec("VP8"));
6500 ASSERT_TRUE(channel_->SetRecvParameters(parameters));
6501
6502 // No streams signaled and no packets received, so we should not have any
6503 // stream objects created yet.
6504 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
6505
6506 // Receive packet on an unsignaled SSRC.
6507 uint8_t data[kMinRtpPacketLen];
6508 cricket::RtpHeader rtp_header;
6509 rtp_header.payload_type = GetEngineCodec("VP8").id;
6510 rtp_header.seq_num = rtp_header.timestamp = 0;
6511 rtp_header.ssrc = kSsrcs3[0];
6512 cricket::SetRtpHeader(data, sizeof(data), rtp_header);
6513 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
6514 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
6515 // Default receive stream should be created.
6516 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
6517 FakeVideoReceiveStream* recv_stream0 =
6518 fake_call_->GetVideoReceiveStreams()[0];
6519 EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);
6520
6521 // Signal the SSRC.
6522 EXPECT_TRUE(
6523 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs3[0])));
6524 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
6525 recv_stream0 = fake_call_->GetVideoReceiveStreams()[0];
6526 EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);
6527
6528 // Receive packet on a different unsignaled SSRC.
6529 rtp_header.ssrc = kSsrcs3[1];
6530 cricket::SetRtpHeader(data, sizeof(data), rtp_header);
6531 packet.SetData(data, sizeof(data));
6532 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
6533 // New default receive stream should be created, but old stream should remain.
6534 ASSERT_EQ(2u, fake_call_->GetVideoReceiveStreams().size());
6535 EXPECT_EQ(recv_stream0, fake_call_->GetVideoReceiveStreams()[0]);
6536 FakeVideoReceiveStream* recv_stream1 =
6537 fake_call_->GetVideoReceiveStreams()[1];
6538 EXPECT_EQ(kSsrcs3[1], recv_stream1->GetConfig().rtp.remote_ssrc);
6539 }
6540
TEST_F(WebRtcVideoChannelTest,CanSetMaxBitrateForExistingStream)6541 TEST_F(WebRtcVideoChannelTest, CanSetMaxBitrateForExistingStream) {
6542 AddSendStream();
6543
6544 webrtc::test::FrameForwarder frame_forwarder;
6545 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
6546 EXPECT_TRUE(channel_->SetSend(true));
6547 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
6548
6549 int default_encoder_bitrate = GetMaxEncoderBitrate();
6550 EXPECT_GT(default_encoder_bitrate, 1000);
6551
6552 // TODO(skvlad): Resolve the inconsistency between the interpretation
6553 // of the global bitrate limit for audio and video:
6554 // - Audio: max_bandwidth_bps = 0 - fail the operation,
6555 // max_bandwidth_bps = -1 - remove the bandwidth limit
6556 // - Video: max_bandwidth_bps = 0 - remove the bandwidth limit,
6557 // max_bandwidth_bps = -1 - remove the bandwidth limit
6558
6559 SetAndExpectMaxBitrate(1000, 0, 1000);
6560 SetAndExpectMaxBitrate(1000, 800, 800);
6561 SetAndExpectMaxBitrate(600, 800, 600);
6562 SetAndExpectMaxBitrate(0, 800, 800);
6563 SetAndExpectMaxBitrate(0, 0, default_encoder_bitrate);
6564
6565 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6566 }
6567
TEST_F(WebRtcVideoChannelTest,CannotSetMaxBitrateForNonexistentStream)6568 TEST_F(WebRtcVideoChannelTest, CannotSetMaxBitrateForNonexistentStream) {
6569 webrtc::RtpParameters nonexistent_parameters =
6570 channel_->GetRtpSendParameters(last_ssrc_);
6571 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
6572
6573 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
6574 EXPECT_FALSE(
6575 channel_->SetRtpSendParameters(last_ssrc_, nonexistent_parameters).ok());
6576 }
6577
TEST_F(WebRtcVideoChannelTest,SetLowMaxBitrateOverwritesVideoStreamMinBitrate)6578 TEST_F(WebRtcVideoChannelTest,
6579 SetLowMaxBitrateOverwritesVideoStreamMinBitrate) {
6580 FakeVideoSendStream* stream = AddSendStream();
6581
6582 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6583 EXPECT_EQ(1UL, parameters.encodings.size());
6584 EXPECT_FALSE(parameters.encodings[0].max_bitrate_bps.has_value());
6585 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6586
6587 // Note that this is testing the behavior of the FakeVideoSendStream, which
6588 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
6589 // we are just testing the behavior of
6590 // EncoderStreamFactory::CreateEncoderStreams.
6591 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6592 EXPECT_EQ(webrtc::kDefaultMinVideoBitrateBps,
6593 stream->GetVideoStreams()[0].min_bitrate_bps);
6594
6595 // Set a low max bitrate & check that VideoStream.min_bitrate_bps is limited
6596 // by this amount.
6597 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6598 int low_max_bitrate_bps = webrtc::kDefaultMinVideoBitrateBps - 1000;
6599 parameters.encodings[0].max_bitrate_bps = low_max_bitrate_bps;
6600 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6601
6602 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6603 EXPECT_EQ(low_max_bitrate_bps, stream->GetVideoStreams()[0].min_bitrate_bps);
6604 EXPECT_EQ(low_max_bitrate_bps, stream->GetVideoStreams()[0].max_bitrate_bps);
6605 }
6606
TEST_F(WebRtcVideoChannelTest,SetHighMinBitrateOverwritesVideoStreamMaxBitrate)6607 TEST_F(WebRtcVideoChannelTest,
6608 SetHighMinBitrateOverwritesVideoStreamMaxBitrate) {
6609 FakeVideoSendStream* stream = AddSendStream();
6610
6611 // Note that this is testing the behavior of the FakeVideoSendStream, which
6612 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
6613 // we are just testing the behavior of
6614 // EncoderStreamFactory::CreateEncoderStreams.
6615 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6616 int high_min_bitrate_bps = stream->GetVideoStreams()[0].max_bitrate_bps + 1;
6617
6618 // Set a high min bitrate and check that max_bitrate_bps is adjusted up.
6619 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6620 EXPECT_EQ(1UL, parameters.encodings.size());
6621 parameters.encodings[0].min_bitrate_bps = high_min_bitrate_bps;
6622 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6623
6624 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6625 EXPECT_EQ(high_min_bitrate_bps, stream->GetVideoStreams()[0].min_bitrate_bps);
6626 EXPECT_EQ(high_min_bitrate_bps, stream->GetVideoStreams()[0].max_bitrate_bps);
6627 }
6628
TEST_F(WebRtcVideoChannelTest,SetMinBitrateAboveMaxBitrateLimitAdjustsMinBitrateDown)6629 TEST_F(WebRtcVideoChannelTest,
6630 SetMinBitrateAboveMaxBitrateLimitAdjustsMinBitrateDown) {
6631 send_parameters_.max_bandwidth_bps = 99999;
6632 FakeVideoSendStream* stream = AddSendStream();
6633 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
6634 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
6635 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6636 EXPECT_EQ(webrtc::kDefaultMinVideoBitrateBps,
6637 stream->GetVideoStreams()[0].min_bitrate_bps);
6638 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
6639 stream->GetVideoStreams()[0].max_bitrate_bps);
6640
6641 // Set min bitrate above global max bitrate and check that min_bitrate_bps is
6642 // adjusted down.
6643 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6644 EXPECT_EQ(1UL, parameters.encodings.size());
6645 parameters.encodings[0].min_bitrate_bps = 99999 + 1;
6646 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6647 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6648 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
6649 stream->GetVideoStreams()[0].min_bitrate_bps);
6650 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
6651 stream->GetVideoStreams()[0].max_bitrate_bps);
6652 }
6653
TEST_F(WebRtcVideoChannelTest,SetMaxFramerateOneStream)6654 TEST_F(WebRtcVideoChannelTest, SetMaxFramerateOneStream) {
6655 FakeVideoSendStream* stream = AddSendStream();
6656
6657 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6658 EXPECT_EQ(1UL, parameters.encodings.size());
6659 EXPECT_FALSE(parameters.encodings[0].max_framerate.has_value());
6660 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6661
6662 // Note that this is testing the behavior of the FakeVideoSendStream, which
6663 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
6664 // we are just testing the behavior of
6665 // EncoderStreamFactory::CreateEncoderStreams.
6666 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6667 EXPECT_EQ(kDefaultVideoMaxFramerate,
6668 stream->GetVideoStreams()[0].max_framerate);
6669
6670 // Set max framerate and check that VideoStream.max_framerate is set.
6671 const int kNewMaxFramerate = kDefaultVideoMaxFramerate - 1;
6672 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6673 parameters.encodings[0].max_framerate = kNewMaxFramerate;
6674 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6675
6676 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6677 EXPECT_EQ(kNewMaxFramerate, stream->GetVideoStreams()[0].max_framerate);
6678 }
6679
TEST_F(WebRtcVideoChannelTest,SetNumTemporalLayersForSingleStream)6680 TEST_F(WebRtcVideoChannelTest, SetNumTemporalLayersForSingleStream) {
6681 FakeVideoSendStream* stream = AddSendStream();
6682
6683 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6684 EXPECT_EQ(1UL, parameters.encodings.size());
6685 EXPECT_FALSE(parameters.encodings[0].num_temporal_layers.has_value());
6686 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6687
6688 // Note that this is testing the behavior of the FakeVideoSendStream, which
6689 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
6690 // we are just testing the behavior of
6691 // EncoderStreamFactory::CreateEncoderStreams.
6692 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6693 EXPECT_FALSE(stream->GetVideoStreams()[0].num_temporal_layers.has_value());
6694
6695 // Set temporal layers and check that VideoStream.num_temporal_layers is set.
6696 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6697 parameters.encodings[0].num_temporal_layers = 2;
6698 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6699
6700 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6701 EXPECT_EQ(2UL, stream->GetVideoStreams()[0].num_temporal_layers);
6702 }
6703
TEST_F(WebRtcVideoChannelTest,CannotSetRtpSendParametersWithIncorrectNumberOfEncodings)6704 TEST_F(WebRtcVideoChannelTest,
6705 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
6706 AddSendStream();
6707 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6708 // Two or more encodings should result in failure.
6709 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
6710 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6711 // Zero encodings should also fail.
6712 parameters.encodings.clear();
6713 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6714 }
6715
TEST_F(WebRtcVideoChannelTest,CannotSetSimulcastRtpSendParametersWithIncorrectNumberOfEncodings)6716 TEST_F(WebRtcVideoChannelTest,
6717 CannotSetSimulcastRtpSendParametersWithIncorrectNumberOfEncodings) {
6718 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
6719 StreamParams sp = CreateSimStreamParams("cname", ssrcs);
6720 AddSendStream(sp);
6721
6722 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6723
6724 // Additional encodings should result in failure.
6725 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
6726 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6727 // Zero encodings should also fail.
6728 parameters.encodings.clear();
6729 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6730 }
6731
6732 // Changing the SSRC through RtpParameters is not allowed.
TEST_F(WebRtcVideoChannelTest,CannotSetSsrcInRtpSendParameters)6733 TEST_F(WebRtcVideoChannelTest, CannotSetSsrcInRtpSendParameters) {
6734 AddSendStream();
6735 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6736 parameters.encodings[0].ssrc = 0xdeadbeef;
6737 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6738 }
6739
6740 // Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
6741 // a value <= 0, setting the parameters returns false.
TEST_F(WebRtcVideoChannelTest,SetRtpSendParametersInvalidBitratePriority)6742 TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersInvalidBitratePriority) {
6743 AddSendStream();
6744 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6745 EXPECT_EQ(1UL, parameters.encodings.size());
6746 EXPECT_EQ(webrtc::kDefaultBitratePriority,
6747 parameters.encodings[0].bitrate_priority);
6748
6749 parameters.encodings[0].bitrate_priority = 0;
6750 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6751 parameters.encodings[0].bitrate_priority = -2;
6752 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6753 }
6754
6755 // Tests when the the RTCRtpEncodingParameters.bitrate_priority gets set
6756 // properly on the VideoChannel and propogates down to the video encoder.
TEST_F(WebRtcVideoChannelTest,SetRtpSendParametersPriorityOneStream)6757 TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersPriorityOneStream) {
6758 AddSendStream();
6759 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6760 EXPECT_EQ(1UL, parameters.encodings.size());
6761 EXPECT_EQ(webrtc::kDefaultBitratePriority,
6762 parameters.encodings[0].bitrate_priority);
6763
6764 // Change the value and set it on the VideoChannel.
6765 double new_bitrate_priority = 2.0;
6766 parameters.encodings[0].bitrate_priority = new_bitrate_priority;
6767 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6768
6769 // Verify that the encoding parameters bitrate_priority is set for the
6770 // VideoChannel.
6771 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6772 EXPECT_EQ(1UL, parameters.encodings.size());
6773 EXPECT_EQ(new_bitrate_priority, parameters.encodings[0].bitrate_priority);
6774
6775 // Verify that the new value propagated down to the encoder.
6776 std::vector<FakeVideoSendStream*> video_send_streams =
6777 fake_call_->GetVideoSendStreams();
6778 EXPECT_EQ(1UL, video_send_streams.size());
6779 FakeVideoSendStream* video_send_stream = video_send_streams.front();
6780 // Check that the WebRtcVideoSendStream updated the VideoEncoderConfig
6781 // appropriately.
6782 EXPECT_EQ(new_bitrate_priority,
6783 video_send_stream->GetEncoderConfig().bitrate_priority);
6784 // Check that the vector of VideoStreams also was propagated correctly. Note
6785 // that this is testing the behavior of the FakeVideoSendStream, which mimics
6786 // the calls to CreateEncoderStreams to get the VideoStreams.
6787 EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
6788 video_send_stream->GetVideoStreams()[0].bitrate_priority);
6789 }
6790
6791 // Tests that the RTCRtpEncodingParameters.bitrate_priority is set for the
6792 // VideoChannel and the value propogates to the video encoder with all simulcast
6793 // streams.
TEST_F(WebRtcVideoChannelTest,SetRtpSendParametersPrioritySimulcastStreams)6794 TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersPrioritySimulcastStreams) {
6795 // Create the stream params with multiple ssrcs for simulcast.
6796 const size_t kNumSimulcastStreams = 3;
6797 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
6798 StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
6799 AddSendStream(stream_params);
6800 uint32_t primary_ssrc = stream_params.first_ssrc();
6801
6802 // Using the FrameForwarder, we manually send a full size
6803 // frame. This creates multiple VideoStreams for all simulcast layers when
6804 // reconfiguring, and allows us to test this behavior.
6805 webrtc::test::FrameForwarder frame_forwarder;
6806 VideoOptions options;
6807 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
6808 channel_->SetSend(true);
6809 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
6810 1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
6811 rtc::kNumMicrosecsPerSec / 30));
6812
6813 // Get and set the rtp encoding parameters.
6814 webrtc::RtpParameters parameters =
6815 channel_->GetRtpSendParameters(primary_ssrc);
6816 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6817 EXPECT_EQ(webrtc::kDefaultBitratePriority,
6818 parameters.encodings[0].bitrate_priority);
6819 // Change the value and set it on the VideoChannel.
6820 double new_bitrate_priority = 2.0;
6821 parameters.encodings[0].bitrate_priority = new_bitrate_priority;
6822 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
6823
6824 // Verify that the encoding parameters priority is set on the VideoChannel.
6825 parameters = channel_->GetRtpSendParameters(primary_ssrc);
6826 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6827 EXPECT_EQ(new_bitrate_priority, parameters.encodings[0].bitrate_priority);
6828
6829 // Verify that the new value propagated down to the encoder.
6830 std::vector<FakeVideoSendStream*> video_send_streams =
6831 fake_call_->GetVideoSendStreams();
6832 EXPECT_EQ(1UL, video_send_streams.size());
6833 FakeVideoSendStream* video_send_stream = video_send_streams.front();
6834 // Check that the WebRtcVideoSendStream updated the VideoEncoderConfig
6835 // appropriately.
6836 EXPECT_EQ(kNumSimulcastStreams,
6837 video_send_stream->GetEncoderConfig().number_of_streams);
6838 EXPECT_EQ(new_bitrate_priority,
6839 video_send_stream->GetEncoderConfig().bitrate_priority);
6840 // Check that the vector of VideoStreams also propagated correctly. The
6841 // FakeVideoSendStream calls CreateEncoderStreams, and we are testing that
6842 // these are created appropriately for the simulcast case.
6843 EXPECT_EQ(kNumSimulcastStreams, video_send_stream->GetVideoStreams().size());
6844 EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
6845 video_send_stream->GetVideoStreams()[0].bitrate_priority);
6846 // Since we are only setting bitrate priority per-sender, the other
6847 // VideoStreams should have a bitrate priority of 0.
6848 EXPECT_EQ(absl::nullopt,
6849 video_send_stream->GetVideoStreams()[1].bitrate_priority);
6850 EXPECT_EQ(absl::nullopt,
6851 video_send_stream->GetVideoStreams()[2].bitrate_priority);
6852 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
6853 }
6854
TEST_F(WebRtcVideoChannelTest,GetAndSetRtpSendParametersScaleResolutionDownByVP8)6855 TEST_F(WebRtcVideoChannelTest,
6856 GetAndSetRtpSendParametersScaleResolutionDownByVP8) {
6857 VideoSendParameters parameters;
6858 parameters.codecs.push_back(VideoCodec(kVp8CodecName));
6859 ASSERT_TRUE(channel_->SetSendParameters(parameters));
6860 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6861
6862 webrtc::test::FrameForwarder frame_forwarder;
6863 FakeFrameSource frame_source(1280, 720, rtc::kNumMicrosecsPerSec / 30);
6864
6865 VideoOptions options;
6866 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
6867 channel_->SetSend(true);
6868
6869 // Try layers in natural order (smallest to largest).
6870 {
6871 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6872 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6873 rtp_parameters.encodings[0].scale_resolution_down_by = 4.0;
6874 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6875 rtp_parameters.encodings[2].scale_resolution_down_by = 1.0;
6876 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6877 ASSERT_TRUE(result.ok());
6878
6879 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6880
6881 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6882 ASSERT_EQ(3u, video_streams.size());
6883 EXPECT_EQ(320u, video_streams[0].width);
6884 EXPECT_EQ(180u, video_streams[0].height);
6885 EXPECT_EQ(640u, video_streams[1].width);
6886 EXPECT_EQ(360u, video_streams[1].height);
6887 EXPECT_EQ(1280u, video_streams[2].width);
6888 EXPECT_EQ(720u, video_streams[2].height);
6889 }
6890
6891 // Try layers in reverse natural order (largest to smallest).
6892 {
6893 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6894 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6895 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6896 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6897 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6898 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6899 ASSERT_TRUE(result.ok());
6900
6901 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6902
6903 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6904 ASSERT_EQ(3u, video_streams.size());
6905 EXPECT_EQ(1280u, video_streams[0].width);
6906 EXPECT_EQ(720u, video_streams[0].height);
6907 EXPECT_EQ(640u, video_streams[1].width);
6908 EXPECT_EQ(360u, video_streams[1].height);
6909 EXPECT_EQ(320u, video_streams[2].width);
6910 EXPECT_EQ(180u, video_streams[2].height);
6911 }
6912
6913 // Try layers in mixed order.
6914 {
6915 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6916 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6917 rtp_parameters.encodings[0].scale_resolution_down_by = 10.0;
6918 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6919 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6920 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6921 ASSERT_TRUE(result.ok());
6922
6923 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6924
6925 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6926 ASSERT_EQ(3u, video_streams.size());
6927 EXPECT_EQ(128u, video_streams[0].width);
6928 EXPECT_EQ(72u, video_streams[0].height);
6929 EXPECT_EQ(640u, video_streams[1].width);
6930 EXPECT_EQ(360u, video_streams[1].height);
6931 EXPECT_EQ(320u, video_streams[2].width);
6932 EXPECT_EQ(180u, video_streams[2].height);
6933 }
6934
6935 // Try with a missing scale setting, defaults to 1.0 if any other is set.
6936 {
6937 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6938 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6939 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6940 rtp_parameters.encodings[1].scale_resolution_down_by.reset();
6941 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6942 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6943 ASSERT_TRUE(result.ok());
6944
6945 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6946
6947 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6948 ASSERT_EQ(3u, video_streams.size());
6949 EXPECT_EQ(1280u, video_streams[0].width);
6950 EXPECT_EQ(720u, video_streams[0].height);
6951 EXPECT_EQ(1280u, video_streams[1].width);
6952 EXPECT_EQ(720u, video_streams[1].height);
6953 EXPECT_EQ(320u, video_streams[2].width);
6954 EXPECT_EQ(180u, video_streams[2].height);
6955 }
6956
6957 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6958 }
6959
TEST_F(WebRtcVideoChannelTest,GetAndSetRtpSendParametersScaleResolutionDownByVP8WithOddResolution)6960 TEST_F(WebRtcVideoChannelTest,
6961 GetAndSetRtpSendParametersScaleResolutionDownByVP8WithOddResolution) {
6962 // Ensure that the top layer has width and height divisible by 2^3,
6963 // so that the bottom layer has width and height divisible by 2.
6964 // TODO(bugs.webrtc.org/8785): Remove this field trial when we fully trust
6965 // the number of simulcast layers set by the app.
6966 webrtc::test::ScopedFieldTrials field_trial(
6967 "WebRTC-NormalizeSimulcastResolution/Enabled-3/");
6968
6969 // Set up WebRtcVideoChannel for 3-layer VP8 simulcast.
6970 VideoSendParameters parameters;
6971 parameters.codecs.push_back(VideoCodec(kVp8CodecName));
6972 ASSERT_TRUE(channel_->SetSendParameters(parameters));
6973 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6974 webrtc::test::FrameForwarder frame_forwarder;
6975 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, /*options=*/nullptr,
6976 &frame_forwarder));
6977 channel_->SetSend(true);
6978
6979 // Set |scale_resolution_down_by|'s.
6980 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6981 ASSERT_EQ(rtp_parameters.encodings.size(), 3u);
6982 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6983 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6984 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6985 const auto result =
6986 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6987 ASSERT_TRUE(result.ok());
6988
6989 // Use a capture resolution whose width and height are not divisible by 2^3.
6990 // (See field trial set at the top of the test.)
6991 FakeFrameSource frame_source(2007, 1207, rtc::kNumMicrosecsPerSec / 30);
6992 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6993
6994 // Ensure the scaling is correct.
6995 const auto video_streams = stream->GetVideoStreams();
6996 ASSERT_EQ(video_streams.size(), 3u);
6997 // Ensure that we round the capture resolution down for the top layer...
6998 EXPECT_EQ(video_streams[0].width, 2000u);
6999 EXPECT_EQ(video_streams[0].height, 1200u);
7000 EXPECT_EQ(video_streams[1].width, 1000u);
7001 EXPECT_EQ(video_streams[1].height, 600u);
7002 // ...and that the bottom layer has a width/height divisible by 2.
7003 EXPECT_EQ(video_streams[2].width, 500u);
7004 EXPECT_EQ(video_streams[2].height, 300u);
7005
7006 // Tear down.
7007 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7008 }
7009
TEST_F(WebRtcVideoChannelTest,GetAndSetRtpSendParametersScaleResolutionDownByH264)7010 TEST_F(WebRtcVideoChannelTest,
7011 GetAndSetRtpSendParametersScaleResolutionDownByH264) {
7012 encoder_factory_->AddSupportedVideoCodecType(kH264CodecName);
7013 VideoSendParameters parameters;
7014 parameters.codecs.push_back(VideoCodec(kH264CodecName));
7015 ASSERT_TRUE(channel_->SetSendParameters(parameters));
7016 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7017
7018 webrtc::test::FrameForwarder frame_forwarder;
7019 FakeFrameSource frame_source(1280, 720, rtc::kNumMicrosecsPerSec / 30);
7020
7021 VideoOptions options;
7022 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
7023 channel_->SetSend(true);
7024
7025 // Try layers in natural order (smallest to largest).
7026 {
7027 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
7028 ASSERT_EQ(3u, rtp_parameters.encodings.size());
7029 rtp_parameters.encodings[0].scale_resolution_down_by = 4.0;
7030 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
7031 rtp_parameters.encodings[2].scale_resolution_down_by = 1.0;
7032 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
7033 ASSERT_TRUE(result.ok());
7034
7035 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
7036
7037 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
7038 ASSERT_EQ(3u, video_streams.size());
7039 EXPECT_EQ(320u, video_streams[0].width);
7040 EXPECT_EQ(180u, video_streams[0].height);
7041 EXPECT_EQ(640u, video_streams[1].width);
7042 EXPECT_EQ(360u, video_streams[1].height);
7043 EXPECT_EQ(1280u, video_streams[2].width);
7044 EXPECT_EQ(720u, video_streams[2].height);
7045 }
7046
7047 // Try layers in reverse natural order (largest to smallest).
7048 {
7049 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
7050 ASSERT_EQ(3u, rtp_parameters.encodings.size());
7051 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
7052 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
7053 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
7054 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
7055 ASSERT_TRUE(result.ok());
7056
7057 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
7058
7059 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
7060 ASSERT_EQ(3u, video_streams.size());
7061 EXPECT_EQ(1280u, video_streams[0].width);
7062 EXPECT_EQ(720u, video_streams[0].height);
7063 EXPECT_EQ(640u, video_streams[1].width);
7064 EXPECT_EQ(360u, video_streams[1].height);
7065 EXPECT_EQ(320u, video_streams[2].width);
7066 EXPECT_EQ(180u, video_streams[2].height);
7067 }
7068
7069 // Try layers in mixed order.
7070 {
7071 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
7072 ASSERT_EQ(3u, rtp_parameters.encodings.size());
7073 rtp_parameters.encodings[0].scale_resolution_down_by = 10.0;
7074 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
7075 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
7076 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
7077 ASSERT_TRUE(result.ok());
7078
7079 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
7080
7081 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
7082 ASSERT_EQ(3u, video_streams.size());
7083 EXPECT_EQ(128u, video_streams[0].width);
7084 EXPECT_EQ(72u, video_streams[0].height);
7085 EXPECT_EQ(640u, video_streams[1].width);
7086 EXPECT_EQ(360u, video_streams[1].height);
7087 EXPECT_EQ(320u, video_streams[2].width);
7088 EXPECT_EQ(180u, video_streams[2].height);
7089 }
7090
7091 // Try with a missing scale setting, defaults to 1.0 if any other is set.
7092 {
7093 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
7094 ASSERT_EQ(3u, rtp_parameters.encodings.size());
7095 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
7096 rtp_parameters.encodings[1].scale_resolution_down_by.reset();
7097 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
7098 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
7099 ASSERT_TRUE(result.ok());
7100
7101 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
7102
7103 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
7104 ASSERT_EQ(3u, video_streams.size());
7105 EXPECT_EQ(1280u, video_streams[0].width);
7106 EXPECT_EQ(720u, video_streams[0].height);
7107 EXPECT_EQ(1280u, video_streams[1].width);
7108 EXPECT_EQ(720u, video_streams[1].height);
7109 EXPECT_EQ(320u, video_streams[2].width);
7110 EXPECT_EQ(180u, video_streams[2].height);
7111 }
7112 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7113 }
7114
TEST_F(WebRtcVideoChannelTest,GetAndSetRtpSendParametersScaleResolutionDownByH264WithOddResolution)7115 TEST_F(WebRtcVideoChannelTest,
7116 GetAndSetRtpSendParametersScaleResolutionDownByH264WithOddResolution) {
7117 // Ensure that the top layer has width and height divisible by 2^3,
7118 // so that the bottom layer has width and height divisible by 2.
7119 // TODO(bugs.webrtc.org/8785): Remove this field trial when we fully trust
7120 // the number of simulcast layers set by the app.
7121 webrtc::test::ScopedFieldTrials field_trial(
7122 "WebRTC-NormalizeSimulcastResolution/Enabled-3/");
7123
7124 // Set up WebRtcVideoChannel for 3-layer H264 simulcast.
7125 encoder_factory_->AddSupportedVideoCodecType(kH264CodecName);
7126 VideoSendParameters parameters;
7127 parameters.codecs.push_back(VideoCodec(kH264CodecName));
7128 ASSERT_TRUE(channel_->SetSendParameters(parameters));
7129 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7130 webrtc::test::FrameForwarder frame_forwarder;
7131 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, /*options=*/nullptr,
7132 &frame_forwarder));
7133 channel_->SetSend(true);
7134
7135 // Set |scale_resolution_down_by|'s.
7136 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
7137 ASSERT_EQ(rtp_parameters.encodings.size(), 3u);
7138 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
7139 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
7140 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
7141 const auto result =
7142 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
7143 ASSERT_TRUE(result.ok());
7144
7145 // Use a capture resolution whose width and height are not divisible by 2^3.
7146 // (See field trial set at the top of the test.)
7147 FakeFrameSource frame_source(2007, 1207, rtc::kNumMicrosecsPerSec / 30);
7148 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
7149
7150 // Ensure the scaling is correct.
7151 const auto video_streams = stream->GetVideoStreams();
7152 ASSERT_EQ(video_streams.size(), 3u);
7153 // Ensure that we round the capture resolution down for the top layer...
7154 EXPECT_EQ(video_streams[0].width, 2000u);
7155 EXPECT_EQ(video_streams[0].height, 1200u);
7156 EXPECT_EQ(video_streams[1].width, 1000u);
7157 EXPECT_EQ(video_streams[1].height, 600u);
7158 // ...and that the bottom layer has a width/height divisible by 2.
7159 EXPECT_EQ(video_streams[2].width, 500u);
7160 EXPECT_EQ(video_streams[2].height, 300u);
7161
7162 // Tear down.
7163 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7164 }
7165
TEST_F(WebRtcVideoChannelTest,GetAndSetRtpSendParametersMaxFramerate)7166 TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersMaxFramerate) {
7167 const size_t kNumSimulcastStreams = 3;
7168 SetUpSimulcast(true, false);
7169
7170 // Get and set the rtp encoding parameters.
7171 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7172 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7173 for (const auto& encoding : parameters.encodings) {
7174 EXPECT_FALSE(encoding.max_framerate);
7175 }
7176
7177 // Change the value and set it on the VideoChannel.
7178 parameters.encodings[0].max_framerate = 10;
7179 parameters.encodings[1].max_framerate = 20;
7180 parameters.encodings[2].max_framerate = 25;
7181 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7182
7183 // Verify that the bitrates are set on the VideoChannel.
7184 parameters = channel_->GetRtpSendParameters(last_ssrc_);
7185 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7186 EXPECT_EQ(10, parameters.encodings[0].max_framerate);
7187 EXPECT_EQ(20, parameters.encodings[1].max_framerate);
7188 EXPECT_EQ(25, parameters.encodings[2].max_framerate);
7189 }
7190
TEST_F(WebRtcVideoChannelTest,SetRtpSendParametersNumTemporalLayersFailsForInvalidRange)7191 TEST_F(WebRtcVideoChannelTest,
7192 SetRtpSendParametersNumTemporalLayersFailsForInvalidRange) {
7193 const size_t kNumSimulcastStreams = 3;
7194 SetUpSimulcast(true, false);
7195
7196 // Get and set the rtp encoding parameters.
7197 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7198 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7199
7200 // Num temporal layers should be in the range [1, kMaxTemporalStreams].
7201 parameters.encodings[0].num_temporal_layers = 0;
7202 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
7203 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
7204 parameters.encodings[0].num_temporal_layers = webrtc::kMaxTemporalStreams + 1;
7205 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
7206 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
7207 }
7208
TEST_F(WebRtcVideoChannelTest,SetRtpSendParametersNumTemporalLayersFailsForInvalidModification)7209 TEST_F(WebRtcVideoChannelTest,
7210 SetRtpSendParametersNumTemporalLayersFailsForInvalidModification) {
7211 const size_t kNumSimulcastStreams = 3;
7212 SetUpSimulcast(true, false);
7213
7214 // Get and set the rtp encoding parameters.
7215 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7216 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7217
7218 // No/all layers should be set.
7219 parameters.encodings[0].num_temporal_layers = 1;
7220 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION,
7221 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
7222
7223 // Different values not supported.
7224 parameters.encodings[0].num_temporal_layers = 1;
7225 parameters.encodings[1].num_temporal_layers = 2;
7226 parameters.encodings[2].num_temporal_layers = 2;
7227 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION,
7228 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
7229 }
7230
TEST_F(WebRtcVideoChannelTest,GetAndSetRtpSendParametersNumTemporalLayers)7231 TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersNumTemporalLayers) {
7232 const size_t kNumSimulcastStreams = 3;
7233 SetUpSimulcast(true, false);
7234
7235 // Get and set the rtp encoding parameters.
7236 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7237 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7238 for (const auto& encoding : parameters.encodings)
7239 EXPECT_FALSE(encoding.num_temporal_layers);
7240
7241 // Change the value and set it on the VideoChannel.
7242 parameters.encodings[0].num_temporal_layers = 3;
7243 parameters.encodings[1].num_temporal_layers = 3;
7244 parameters.encodings[2].num_temporal_layers = 3;
7245 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7246
7247 // Verify that the number of temporal layers are set on the VideoChannel.
7248 parameters = channel_->GetRtpSendParameters(last_ssrc_);
7249 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7250 EXPECT_EQ(3, parameters.encodings[0].num_temporal_layers);
7251 EXPECT_EQ(3, parameters.encodings[1].num_temporal_layers);
7252 EXPECT_EQ(3, parameters.encodings[2].num_temporal_layers);
7253 }
7254
TEST_F(WebRtcVideoChannelTest,NumTemporalLayersPropagatedToEncoder)7255 TEST_F(WebRtcVideoChannelTest, NumTemporalLayersPropagatedToEncoder) {
7256 const size_t kNumSimulcastStreams = 3;
7257 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7258
7259 // Send a full size frame so all simulcast layers are used when reconfiguring.
7260 webrtc::test::FrameForwarder frame_forwarder;
7261 VideoOptions options;
7262 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
7263 channel_->SetSend(true);
7264 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
7265
7266 // Get and set the rtp encoding parameters.
7267 // Change the value and set it on the VideoChannel.
7268 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7269 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7270 parameters.encodings[0].num_temporal_layers = 2;
7271 parameters.encodings[1].num_temporal_layers = 2;
7272 parameters.encodings[2].num_temporal_layers = 2;
7273 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7274
7275 // Verify that the new value is propagated down to the encoder.
7276 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
7277 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
7278 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
7279 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
7280 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
7281 EXPECT_EQ(2UL, encoder_config.simulcast_layers[0].num_temporal_layers);
7282 EXPECT_EQ(2UL, encoder_config.simulcast_layers[1].num_temporal_layers);
7283 EXPECT_EQ(2UL, encoder_config.simulcast_layers[2].num_temporal_layers);
7284
7285 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
7286 // VideoStreams are created appropriately for the simulcast case.
7287 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7288 EXPECT_EQ(2UL, stream->GetVideoStreams()[0].num_temporal_layers);
7289 EXPECT_EQ(2UL, stream->GetVideoStreams()[1].num_temporal_layers);
7290 EXPECT_EQ(2UL, stream->GetVideoStreams()[2].num_temporal_layers);
7291
7292 // No parameter changed, encoder should not be reconfigured.
7293 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7294 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
7295
7296 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7297 }
7298
TEST_F(WebRtcVideoChannelTest,DefaultValuePropagatedToEncoderForUnsetNumTemporalLayers)7299 TEST_F(WebRtcVideoChannelTest,
7300 DefaultValuePropagatedToEncoderForUnsetNumTemporalLayers) {
7301 const size_t kDefaultNumTemporalLayers = 3;
7302 const size_t kNumSimulcastStreams = 3;
7303 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7304
7305 // Send a full size frame so all simulcast layers are used when reconfiguring.
7306 webrtc::test::FrameForwarder frame_forwarder;
7307 VideoOptions options;
7308 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
7309 channel_->SetSend(true);
7310 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
7311
7312 // Change rtp encoding parameters, num_temporal_layers not changed.
7313 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7314 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7315 parameters.encodings[0].min_bitrate_bps = 33000;
7316 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7317
7318 // Verify that no value is propagated down to the encoder.
7319 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
7320 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
7321 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
7322 EXPECT_FALSE(encoder_config.simulcast_layers[0].num_temporal_layers);
7323 EXPECT_FALSE(encoder_config.simulcast_layers[1].num_temporal_layers);
7324 EXPECT_FALSE(encoder_config.simulcast_layers[2].num_temporal_layers);
7325
7326 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
7327 // VideoStreams are created appropriately for the simulcast case.
7328 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7329 EXPECT_EQ(kDefaultNumTemporalLayers,
7330 stream->GetVideoStreams()[0].num_temporal_layers);
7331 EXPECT_EQ(kDefaultNumTemporalLayers,
7332 stream->GetVideoStreams()[1].num_temporal_layers);
7333 EXPECT_EQ(kDefaultNumTemporalLayers,
7334 stream->GetVideoStreams()[2].num_temporal_layers);
7335
7336 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7337 }
7338
TEST_F(WebRtcVideoChannelTest,DefaultValuePropagatedToEncoderForUnsetFramerate)7339 TEST_F(WebRtcVideoChannelTest,
7340 DefaultValuePropagatedToEncoderForUnsetFramerate) {
7341 const size_t kNumSimulcastStreams = 3;
7342 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
7343 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7344
7345 // Send a full size frame so all simulcast layers are used when reconfiguring.
7346 webrtc::test::FrameForwarder frame_forwarder;
7347 VideoOptions options;
7348 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
7349 channel_->SetSend(true);
7350 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
7351
7352 // Get and set the rtp encoding parameters.
7353 // Change the value and set it on the VideoChannel.
7354 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7355 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7356 parameters.encodings[0].max_framerate = 15;
7357 parameters.encodings[2].max_framerate = 20;
7358 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7359
7360 // Verify that the new value propagated down to the encoder.
7361 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
7362 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
7363 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
7364 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
7365 EXPECT_EQ(15, encoder_config.simulcast_layers[0].max_framerate);
7366 EXPECT_EQ(-1, encoder_config.simulcast_layers[1].max_framerate);
7367 EXPECT_EQ(20, encoder_config.simulcast_layers[2].max_framerate);
7368
7369 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
7370 // VideoStreams are created appropriately for the simulcast case.
7371 // The maximum |max_framerate| is used, kDefaultVideoMaxFramerate: 60.
7372 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7373 EXPECT_EQ(15, stream->GetVideoStreams()[0].max_framerate);
7374 EXPECT_EQ(kDefaultVideoMaxFramerate,
7375 stream->GetVideoStreams()[1].max_framerate);
7376 EXPECT_EQ(20, stream->GetVideoStreams()[2].max_framerate);
7377
7378 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7379 }
7380
TEST_F(WebRtcVideoChannelTest,GetAndSetRtpSendParametersMinAndMaxBitrate)7381 TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersMinAndMaxBitrate) {
7382 const size_t kNumSimulcastStreams = 3;
7383 SetUpSimulcast(true, false);
7384
7385 // Get and set the rtp encoding parameters.
7386 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7387 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7388 for (const auto& encoding : parameters.encodings) {
7389 EXPECT_FALSE(encoding.min_bitrate_bps);
7390 EXPECT_FALSE(encoding.max_bitrate_bps);
7391 }
7392
7393 // Change the value and set it on the VideoChannel.
7394 parameters.encodings[0].min_bitrate_bps = 100000;
7395 parameters.encodings[0].max_bitrate_bps = 200000;
7396 parameters.encodings[1].min_bitrate_bps = 300000;
7397 parameters.encodings[1].max_bitrate_bps = 400000;
7398 parameters.encodings[2].min_bitrate_bps = 500000;
7399 parameters.encodings[2].max_bitrate_bps = 600000;
7400 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7401
7402 // Verify that the bitrates are set on the VideoChannel.
7403 parameters = channel_->GetRtpSendParameters(last_ssrc_);
7404 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7405 EXPECT_EQ(100000, parameters.encodings[0].min_bitrate_bps);
7406 EXPECT_EQ(200000, parameters.encodings[0].max_bitrate_bps);
7407 EXPECT_EQ(300000, parameters.encodings[1].min_bitrate_bps);
7408 EXPECT_EQ(400000, parameters.encodings[1].max_bitrate_bps);
7409 EXPECT_EQ(500000, parameters.encodings[2].min_bitrate_bps);
7410 EXPECT_EQ(600000, parameters.encodings[2].max_bitrate_bps);
7411 }
7412
TEST_F(WebRtcVideoChannelTest,SetRtpSendParametersFailsWithIncorrectBitrate)7413 TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersFailsWithIncorrectBitrate) {
7414 const size_t kNumSimulcastStreams = 3;
7415 SetUpSimulcast(true, false);
7416
7417 // Get and set the rtp encoding parameters.
7418 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7419 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7420
7421 // Max bitrate lower than min bitrate should fail.
7422 parameters.encodings[2].min_bitrate_bps = 100000;
7423 parameters.encodings[2].max_bitrate_bps = 100000 - 1;
7424 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
7425 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
7426 }
7427
7428 // Test that min and max bitrate values set via RtpParameters are correctly
7429 // propagated to the underlying encoder, and that the target is set to 3/4 of
7430 // the maximum (3/4 was chosen because it's similar to the simulcast defaults
7431 // that are used if no min/max are specified).
TEST_F(WebRtcVideoChannelTest,MinAndMaxSimulcastBitratePropagatedToEncoder)7432 TEST_F(WebRtcVideoChannelTest, MinAndMaxSimulcastBitratePropagatedToEncoder) {
7433 const size_t kNumSimulcastStreams = 3;
7434 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7435
7436 // Send a full size frame so all simulcast layers are used when reconfiguring.
7437 webrtc::test::FrameForwarder frame_forwarder;
7438 VideoOptions options;
7439 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
7440 channel_->SetSend(true);
7441 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
7442
7443 // Get and set the rtp encoding parameters.
7444 // Change the value and set it on the VideoChannel.
7445 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7446 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7447 parameters.encodings[0].min_bitrate_bps = 100000;
7448 parameters.encodings[0].max_bitrate_bps = 200000;
7449 parameters.encodings[1].min_bitrate_bps = 300000;
7450 parameters.encodings[1].max_bitrate_bps = 400000;
7451 parameters.encodings[2].min_bitrate_bps = 500000;
7452 parameters.encodings[2].max_bitrate_bps = 600000;
7453 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7454
7455 // Verify that the new value propagated down to the encoder.
7456 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
7457 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
7458 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
7459 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
7460 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
7461 EXPECT_EQ(100000, encoder_config.simulcast_layers[0].min_bitrate_bps);
7462 EXPECT_EQ(200000, encoder_config.simulcast_layers[0].max_bitrate_bps);
7463 EXPECT_EQ(300000, encoder_config.simulcast_layers[1].min_bitrate_bps);
7464 EXPECT_EQ(400000, encoder_config.simulcast_layers[1].max_bitrate_bps);
7465 EXPECT_EQ(500000, encoder_config.simulcast_layers[2].min_bitrate_bps);
7466 EXPECT_EQ(600000, encoder_config.simulcast_layers[2].max_bitrate_bps);
7467
7468 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
7469 // VideoStreams are created appropriately for the simulcast case.
7470 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7471 // Target bitrate: 200000 * 3 / 4 = 150000.
7472 EXPECT_EQ(100000, stream->GetVideoStreams()[0].min_bitrate_bps);
7473 EXPECT_EQ(150000, stream->GetVideoStreams()[0].target_bitrate_bps);
7474 EXPECT_EQ(200000, stream->GetVideoStreams()[0].max_bitrate_bps);
7475 // Target bitrate: 400000 * 3 / 4 = 300000.
7476 EXPECT_EQ(300000, stream->GetVideoStreams()[1].min_bitrate_bps);
7477 EXPECT_EQ(300000, stream->GetVideoStreams()[1].target_bitrate_bps);
7478 EXPECT_EQ(400000, stream->GetVideoStreams()[1].max_bitrate_bps);
7479 // Target bitrate: 600000 * 3 / 4 = 450000, less than min -> max.
7480 EXPECT_EQ(500000, stream->GetVideoStreams()[2].min_bitrate_bps);
7481 EXPECT_EQ(600000, stream->GetVideoStreams()[2].target_bitrate_bps);
7482 EXPECT_EQ(600000, stream->GetVideoStreams()[2].max_bitrate_bps);
7483
7484 // No parameter changed, encoder should not be reconfigured.
7485 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7486 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
7487
7488 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7489 }
7490
7491 // Test to only specify the min or max bitrate value for a layer via
7492 // RtpParameters. The unspecified min/max and target value should be set to the
7493 // simulcast default that is used if no min/max are specified.
TEST_F(WebRtcVideoChannelTest,MinOrMaxSimulcastBitratePropagatedToEncoder)7494 TEST_F(WebRtcVideoChannelTest, MinOrMaxSimulcastBitratePropagatedToEncoder) {
7495 const size_t kNumSimulcastStreams = 3;
7496 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
7497 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7498
7499 // Send a full size frame so all simulcast layers are used when reconfiguring.
7500 webrtc::test::FrameForwarder frame_forwarder;
7501 VideoOptions options;
7502 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
7503 channel_->SetSend(true);
7504 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
7505
7506 // Get and set the rtp encoding parameters.
7507 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7508 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7509
7510 // Change the value and set it on the VideoChannel.
7511 // Layer 0: only configure min bitrate.
7512 const int kMinBpsLayer0 = kDefault[0].min_bitrate_bps + 1;
7513 parameters.encodings[0].min_bitrate_bps = kMinBpsLayer0;
7514 // Layer 1: only configure max bitrate.
7515 const int kMaxBpsLayer1 = kDefault[1].max_bitrate_bps - 1;
7516 parameters.encodings[1].max_bitrate_bps = kMaxBpsLayer1;
7517 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7518
7519 // Verify that the new value propagated down to the encoder.
7520 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
7521 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
7522 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
7523 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
7524 EXPECT_EQ(kMinBpsLayer0, encoder_config.simulcast_layers[0].min_bitrate_bps);
7525 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].max_bitrate_bps);
7526 EXPECT_EQ(-1, encoder_config.simulcast_layers[1].min_bitrate_bps);
7527 EXPECT_EQ(kMaxBpsLayer1, encoder_config.simulcast_layers[1].max_bitrate_bps);
7528 EXPECT_EQ(-1, encoder_config.simulcast_layers[2].min_bitrate_bps);
7529 EXPECT_EQ(-1, encoder_config.simulcast_layers[2].max_bitrate_bps);
7530
7531 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
7532 // VideoStreams are created appropriately for the simulcast case.
7533 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7534 // Layer 0: min configured bitrate should overwrite min default.
7535 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].min_bitrate_bps);
7536 EXPECT_EQ(kDefault[0].target_bitrate_bps,
7537 stream->GetVideoStreams()[0].target_bitrate_bps);
7538 EXPECT_EQ(kDefault[0].max_bitrate_bps,
7539 stream->GetVideoStreams()[0].max_bitrate_bps);
7540 // Layer 1: max configured bitrate should overwrite max default.
7541 EXPECT_EQ(kDefault[1].min_bitrate_bps,
7542 stream->GetVideoStreams()[1].min_bitrate_bps);
7543 EXPECT_EQ(kDefault[1].target_bitrate_bps,
7544 stream->GetVideoStreams()[1].target_bitrate_bps);
7545 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].max_bitrate_bps);
7546 // Layer 2: min and max bitrate not configured, default expected.
7547 EXPECT_EQ(kDefault[2].min_bitrate_bps,
7548 stream->GetVideoStreams()[2].min_bitrate_bps);
7549 EXPECT_EQ(kDefault[2].target_bitrate_bps,
7550 stream->GetVideoStreams()[2].target_bitrate_bps);
7551 EXPECT_EQ(kDefault[2].max_bitrate_bps,
7552 stream->GetVideoStreams()[2].max_bitrate_bps);
7553
7554 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7555 }
7556
7557 // Test that specifying the min (or max) bitrate value for a layer via
7558 // RtpParameters above (or below) the simulcast default max (or min) adjusts the
7559 // unspecified values accordingly.
TEST_F(WebRtcVideoChannelTest,SetMinAndMaxSimulcastBitrateAboveBelowDefault)7560 TEST_F(WebRtcVideoChannelTest, SetMinAndMaxSimulcastBitrateAboveBelowDefault) {
7561 const size_t kNumSimulcastStreams = 3;
7562 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
7563 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7564
7565 // Send a full size frame so all simulcast layers are used when reconfiguring.
7566 webrtc::test::FrameForwarder frame_forwarder;
7567 VideoOptions options;
7568 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
7569 channel_->SetSend(true);
7570 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
7571
7572 // Get and set the rtp encoding parameters.
7573 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7574 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7575
7576 // Change the value and set it on the VideoChannel.
7577 // For layer 0, set the min bitrate above the default max.
7578 const int kMinBpsLayer0 = kDefault[0].max_bitrate_bps + 1;
7579 parameters.encodings[0].min_bitrate_bps = kMinBpsLayer0;
7580 // For layer 1, set the max bitrate below the default min.
7581 const int kMaxBpsLayer1 = kDefault[1].min_bitrate_bps - 1;
7582 parameters.encodings[1].max_bitrate_bps = kMaxBpsLayer1;
7583 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7584
7585 // Verify that the new value propagated down to the encoder.
7586 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
7587 // VideoStreams are created appropriately for the simulcast case.
7588 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7589 // Layer 0: Min bitrate above default max (target/max should be adjusted).
7590 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].min_bitrate_bps);
7591 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].target_bitrate_bps);
7592 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].max_bitrate_bps);
7593 // Layer 1: Max bitrate below default min (min/target should be adjusted).
7594 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].min_bitrate_bps);
7595 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].target_bitrate_bps);
7596 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].max_bitrate_bps);
7597 // Layer 2: min and max bitrate not configured, default expected.
7598 EXPECT_EQ(kDefault[2].min_bitrate_bps,
7599 stream->GetVideoStreams()[2].min_bitrate_bps);
7600 EXPECT_EQ(kDefault[2].target_bitrate_bps,
7601 stream->GetVideoStreams()[2].target_bitrate_bps);
7602 EXPECT_EQ(kDefault[2].max_bitrate_bps,
7603 stream->GetVideoStreams()[2].max_bitrate_bps);
7604
7605 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7606 }
7607
TEST_F(WebRtcVideoChannelTest,BandwidthAboveTotalMaxBitrateGivenToMaxLayer)7608 TEST_F(WebRtcVideoChannelTest, BandwidthAboveTotalMaxBitrateGivenToMaxLayer) {
7609 const size_t kNumSimulcastStreams = 3;
7610 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
7611 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7612
7613 // Send a full size frame so all simulcast layers are used when reconfiguring.
7614 webrtc::test::FrameForwarder frame_forwarder;
7615 VideoOptions options;
7616 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
7617 channel_->SetSend(true);
7618 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
7619
7620 // Set max bitrate for all but the highest layer.
7621 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7622 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7623 parameters.encodings[0].max_bitrate_bps = kDefault[0].max_bitrate_bps;
7624 parameters.encodings[1].max_bitrate_bps = kDefault[1].max_bitrate_bps;
7625 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7626
7627 // Set max bandwidth equal to total max bitrate.
7628 send_parameters_.max_bandwidth_bps =
7629 GetTotalMaxBitrate(stream->GetVideoStreams()).bps();
7630 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
7631 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
7632
7633 // No bitrate above the total max to give to the highest layer.
7634 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7635 EXPECT_EQ(kDefault[2].max_bitrate_bps,
7636 stream->GetVideoStreams()[2].max_bitrate_bps);
7637
7638 // Set max bandwidth above the total max bitrate.
7639 send_parameters_.max_bandwidth_bps =
7640 GetTotalMaxBitrate(stream->GetVideoStreams()).bps() + 1;
7641 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
7642 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
7643
7644 // The highest layer has no max bitrate set -> the bitrate above the total
7645 // max should be given to the highest layer.
7646 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7647 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
7648 GetTotalMaxBitrate(stream->GetVideoStreams()).bps());
7649 EXPECT_EQ(kDefault[2].max_bitrate_bps + 1,
7650 stream->GetVideoStreams()[2].max_bitrate_bps);
7651
7652 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7653 }
7654
TEST_F(WebRtcVideoChannelTest,BandwidthAboveTotalMaxBitrateNotGivenToMaxLayerIfMaxBitrateSet)7655 TEST_F(WebRtcVideoChannelTest,
7656 BandwidthAboveTotalMaxBitrateNotGivenToMaxLayerIfMaxBitrateSet) {
7657 const size_t kNumSimulcastStreams = 3;
7658 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
7659 EXPECT_EQ(kNumSimulcastStreams, kDefault.size());
7660 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7661
7662 // Send a full size frame so all simulcast layers are used when reconfiguring.
7663 webrtc::test::FrameForwarder frame_forwarder;
7664 VideoOptions options;
7665 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
7666 channel_->SetSend(true);
7667 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
7668
7669 // Set max bitrate for the highest layer.
7670 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7671 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7672 parameters.encodings[2].max_bitrate_bps = kDefault[2].max_bitrate_bps;
7673 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7674
7675 // Set max bandwidth above the total max bitrate.
7676 send_parameters_.max_bandwidth_bps =
7677 GetTotalMaxBitrate(stream->GetVideoStreams()).bps() + 1;
7678 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
7679 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
7680
7681 // The highest layer has the max bitrate set -> the bitrate above the total
7682 // max should not be given to the highest layer.
7683 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7684 EXPECT_EQ(*parameters.encodings[2].max_bitrate_bps,
7685 stream->GetVideoStreams()[2].max_bitrate_bps);
7686
7687 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7688 }
7689
7690 // Test that min and max bitrate values set via RtpParameters are correctly
7691 // propagated to the underlying encoder for a single stream.
TEST_F(WebRtcVideoChannelTest,MinAndMaxBitratePropagatedToEncoder)7692 TEST_F(WebRtcVideoChannelTest, MinAndMaxBitratePropagatedToEncoder) {
7693 FakeVideoSendStream* stream = AddSendStream();
7694 EXPECT_TRUE(channel_->SetSend(true));
7695 EXPECT_TRUE(stream->IsSending());
7696
7697 // Set min and max bitrate.
7698 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7699 EXPECT_EQ(1u, parameters.encodings.size());
7700 parameters.encodings[0].min_bitrate_bps = 80000;
7701 parameters.encodings[0].max_bitrate_bps = 150000;
7702 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7703
7704 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
7705 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
7706 EXPECT_EQ(1u, encoder_config.number_of_streams);
7707 EXPECT_EQ(1u, encoder_config.simulcast_layers.size());
7708 EXPECT_EQ(80000, encoder_config.simulcast_layers[0].min_bitrate_bps);
7709 EXPECT_EQ(150000, encoder_config.simulcast_layers[0].max_bitrate_bps);
7710
7711 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
7712 // VideoStreams are created appropriately.
7713 EXPECT_EQ(1u, stream->GetVideoStreams().size());
7714 EXPECT_EQ(80000, stream->GetVideoStreams()[0].min_bitrate_bps);
7715 EXPECT_EQ(150000, stream->GetVideoStreams()[0].target_bitrate_bps);
7716 EXPECT_EQ(150000, stream->GetVideoStreams()[0].max_bitrate_bps);
7717 }
7718
7719 // Test the default min and max bitrate value are correctly propagated to the
7720 // underlying encoder for a single stream (when the values are not set via
7721 // RtpParameters).
TEST_F(WebRtcVideoChannelTest,DefaultMinAndMaxBitratePropagatedToEncoder)7722 TEST_F(WebRtcVideoChannelTest, DefaultMinAndMaxBitratePropagatedToEncoder) {
7723 FakeVideoSendStream* stream = AddSendStream();
7724 EXPECT_TRUE(channel_->SetSend(true));
7725 EXPECT_TRUE(stream->IsSending());
7726
7727 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
7728 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
7729 EXPECT_EQ(1u, encoder_config.number_of_streams);
7730 EXPECT_EQ(1u, encoder_config.simulcast_layers.size());
7731 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].min_bitrate_bps);
7732 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].max_bitrate_bps);
7733
7734 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
7735 // VideoStreams are created appropriately.
7736 EXPECT_EQ(1u, stream->GetVideoStreams().size());
7737 EXPECT_EQ(webrtc::kDefaultMinVideoBitrateBps,
7738 stream->GetVideoStreams()[0].min_bitrate_bps);
7739 EXPECT_GT(stream->GetVideoStreams()[0].max_bitrate_bps,
7740 stream->GetVideoStreams()[0].min_bitrate_bps);
7741 EXPECT_EQ(stream->GetVideoStreams()[0].max_bitrate_bps,
7742 stream->GetVideoStreams()[0].target_bitrate_bps);
7743 }
7744
7745 // Test that a stream will not be sending if its encoding is made inactive
7746 // through SetRtpSendParameters.
TEST_F(WebRtcVideoChannelTest,SetRtpSendParametersOneEncodingActive)7747 TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersOneEncodingActive) {
7748 FakeVideoSendStream* stream = AddSendStream();
7749 EXPECT_TRUE(channel_->SetSend(true));
7750 EXPECT_TRUE(stream->IsSending());
7751
7752 // Get current parameters and change "active" to false.
7753 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7754 ASSERT_EQ(1u, parameters.encodings.size());
7755 ASSERT_TRUE(parameters.encodings[0].active);
7756 parameters.encodings[0].active = false;
7757 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7758 EXPECT_FALSE(stream->IsSending());
7759
7760 // Now change it back to active and verify we resume sending.
7761 parameters.encodings[0].active = true;
7762 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7763 EXPECT_TRUE(stream->IsSending());
7764 }
7765
7766 // Tests that when active is updated for any simulcast layer then the send
7767 // stream's sending state will be updated and it will be reconfigured with the
7768 // new appropriate active simulcast streams.
TEST_F(WebRtcVideoChannelTest,SetRtpSendParametersMultipleEncodingsActive)7769 TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersMultipleEncodingsActive) {
7770 // Create the stream params with multiple ssrcs for simulcast.
7771 const size_t kNumSimulcastStreams = 3;
7772 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
7773 StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
7774 FakeVideoSendStream* fake_video_send_stream = AddSendStream(stream_params);
7775 uint32_t primary_ssrc = stream_params.first_ssrc();
7776
7777 // Using the FrameForwarder, we manually send a full size
7778 // frame. This allows us to test that ReconfigureEncoder is called
7779 // appropriately.
7780 webrtc::test::FrameForwarder frame_forwarder;
7781 VideoOptions options;
7782 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
7783 channel_->SetSend(true);
7784 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
7785 1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
7786 rtc::kNumMicrosecsPerSec / 30));
7787
7788 // Check that all encodings are initially active.
7789 webrtc::RtpParameters parameters =
7790 channel_->GetRtpSendParameters(primary_ssrc);
7791 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7792 EXPECT_TRUE(parameters.encodings[0].active);
7793 EXPECT_TRUE(parameters.encodings[1].active);
7794 EXPECT_TRUE(parameters.encodings[2].active);
7795 EXPECT_TRUE(fake_video_send_stream->IsSending());
7796
7797 // Only turn on only the middle stream.
7798 parameters.encodings[0].active = false;
7799 parameters.encodings[1].active = true;
7800 parameters.encodings[2].active = false;
7801 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
7802 // Verify that the active fields are set on the VideoChannel.
7803 parameters = channel_->GetRtpSendParameters(primary_ssrc);
7804 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7805 EXPECT_FALSE(parameters.encodings[0].active);
7806 EXPECT_TRUE(parameters.encodings[1].active);
7807 EXPECT_FALSE(parameters.encodings[2].active);
7808 // Check that the VideoSendStream is updated appropriately. This means its
7809 // send state was updated and it was reconfigured.
7810 EXPECT_TRUE(fake_video_send_stream->IsSending());
7811 std::vector<webrtc::VideoStream> simulcast_streams =
7812 fake_video_send_stream->GetVideoStreams();
7813 EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
7814 EXPECT_FALSE(simulcast_streams[0].active);
7815 EXPECT_TRUE(simulcast_streams[1].active);
7816 EXPECT_FALSE(simulcast_streams[2].active);
7817
7818 // Turn off all streams.
7819 parameters.encodings[0].active = false;
7820 parameters.encodings[1].active = false;
7821 parameters.encodings[2].active = false;
7822 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
7823 // Verify that the active fields are set on the VideoChannel.
7824 parameters = channel_->GetRtpSendParameters(primary_ssrc);
7825 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7826 EXPECT_FALSE(parameters.encodings[0].active);
7827 EXPECT_FALSE(parameters.encodings[1].active);
7828 EXPECT_FALSE(parameters.encodings[2].active);
7829 // Check that the VideoSendStream is off.
7830 EXPECT_FALSE(fake_video_send_stream->IsSending());
7831 simulcast_streams = fake_video_send_stream->GetVideoStreams();
7832 EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
7833 EXPECT_FALSE(simulcast_streams[0].active);
7834 EXPECT_FALSE(simulcast_streams[1].active);
7835 EXPECT_FALSE(simulcast_streams[2].active);
7836
7837 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
7838 }
7839
7840 // Test that if a stream is reconfigured (due to a codec change or other
7841 // change) while its encoding is still inactive, it doesn't start sending.
TEST_F(WebRtcVideoChannelTest,InactiveStreamDoesntStartSendingWhenReconfigured)7842 TEST_F(WebRtcVideoChannelTest,
7843 InactiveStreamDoesntStartSendingWhenReconfigured) {
7844 // Set an initial codec list, which will be modified later.
7845 cricket::VideoSendParameters parameters1;
7846 parameters1.codecs.push_back(GetEngineCodec("VP8"));
7847 parameters1.codecs.push_back(GetEngineCodec("VP9"));
7848 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
7849
7850 FakeVideoSendStream* stream = AddSendStream();
7851 EXPECT_TRUE(channel_->SetSend(true));
7852 EXPECT_TRUE(stream->IsSending());
7853
7854 // Get current parameters and change "active" to false.
7855 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7856 ASSERT_EQ(1u, parameters.encodings.size());
7857 ASSERT_TRUE(parameters.encodings[0].active);
7858 parameters.encodings[0].active = false;
7859 EXPECT_EQ(1u, GetFakeSendStreams().size());
7860 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
7861 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7862 EXPECT_FALSE(stream->IsSending());
7863
7864 // Reorder the codec list, causing the stream to be reconfigured.
7865 cricket::VideoSendParameters parameters2;
7866 parameters2.codecs.push_back(GetEngineCodec("VP9"));
7867 parameters2.codecs.push_back(GetEngineCodec("VP8"));
7868 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
7869 auto new_streams = GetFakeSendStreams();
7870 // Assert that a new underlying stream was created due to the codec change.
7871 // Otherwise, this test isn't testing what it set out to test.
7872 EXPECT_EQ(1u, GetFakeSendStreams().size());
7873 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
7874
7875 // Verify that we still are not sending anything, due to the inactive
7876 // encoding.
7877 EXPECT_FALSE(new_streams[0]->IsSending());
7878 }
7879
7880 // Test that GetRtpSendParameters returns the currently configured codecs.
TEST_F(WebRtcVideoChannelTest,GetRtpSendParametersCodecs)7881 TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersCodecs) {
7882 AddSendStream();
7883 cricket::VideoSendParameters parameters;
7884 parameters.codecs.push_back(GetEngineCodec("VP8"));
7885 parameters.codecs.push_back(GetEngineCodec("VP9"));
7886 EXPECT_TRUE(channel_->SetSendParameters(parameters));
7887
7888 webrtc::RtpParameters rtp_parameters =
7889 channel_->GetRtpSendParameters(last_ssrc_);
7890 ASSERT_EQ(2u, rtp_parameters.codecs.size());
7891 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
7892 rtp_parameters.codecs[0]);
7893 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
7894 rtp_parameters.codecs[1]);
7895 }
7896
7897 // Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
TEST_F(WebRtcVideoChannelTest,GetRtpSendParametersRtcpCname)7898 TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersRtcpCname) {
7899 StreamParams params = StreamParams::CreateLegacy(kSsrc);
7900 params.cname = "rtcpcname";
7901 AddSendStream(params);
7902
7903 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc);
7904 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
7905 }
7906
7907 // Test that RtpParameters for send stream has one encoding and it has
7908 // the correct SSRC.
TEST_F(WebRtcVideoChannelTest,GetRtpSendParametersSsrc)7909 TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersSsrc) {
7910 AddSendStream();
7911
7912 webrtc::RtpParameters rtp_parameters =
7913 channel_->GetRtpSendParameters(last_ssrc_);
7914 ASSERT_EQ(1u, rtp_parameters.encodings.size());
7915 EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc);
7916 }
7917
TEST_F(WebRtcVideoChannelTest,DetectRtpSendParameterHeaderExtensionsChange)7918 TEST_F(WebRtcVideoChannelTest, DetectRtpSendParameterHeaderExtensionsChange) {
7919 AddSendStream();
7920
7921 webrtc::RtpParameters rtp_parameters =
7922 channel_->GetRtpSendParameters(last_ssrc_);
7923 rtp_parameters.header_extensions.emplace_back();
7924
7925 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
7926
7927 webrtc::RTCError result =
7928 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
7929 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
7930 }
7931
TEST_F(WebRtcVideoChannelTest,GetRtpSendParametersDegradationPreference)7932 TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersDegradationPreference) {
7933 AddSendStream();
7934
7935 webrtc::test::FrameForwarder frame_forwarder;
7936 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
7937
7938 webrtc::RtpParameters rtp_parameters =
7939 channel_->GetRtpSendParameters(last_ssrc_);
7940 EXPECT_FALSE(rtp_parameters.degradation_preference.has_value());
7941 rtp_parameters.degradation_preference =
7942 webrtc::DegradationPreference::MAINTAIN_FRAMERATE;
7943
7944 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
7945
7946 webrtc::RtpParameters updated_rtp_parameters =
7947 channel_->GetRtpSendParameters(last_ssrc_);
7948 EXPECT_EQ(updated_rtp_parameters.degradation_preference,
7949 webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
7950
7951 // Remove the source since it will be destroyed before the channel
7952 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7953 }
7954
7955 // Test that if we set/get parameters multiple times, we get the same results.
TEST_F(WebRtcVideoChannelTest,SetAndGetRtpSendParameters)7956 TEST_F(WebRtcVideoChannelTest, SetAndGetRtpSendParameters) {
7957 AddSendStream();
7958 cricket::VideoSendParameters parameters;
7959 parameters.codecs.push_back(GetEngineCodec("VP8"));
7960 parameters.codecs.push_back(GetEngineCodec("VP9"));
7961 EXPECT_TRUE(channel_->SetSendParameters(parameters));
7962
7963 webrtc::RtpParameters initial_params =
7964 channel_->GetRtpSendParameters(last_ssrc_);
7965
7966 // We should be able to set the params we just got.
7967 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, initial_params).ok());
7968
7969 // ... And this shouldn't change the params returned by GetRtpSendParameters.
7970 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(last_ssrc_));
7971 }
7972
7973 // Test that GetRtpReceiveParameters returns the currently configured codecs.
TEST_F(WebRtcVideoChannelTest,GetRtpReceiveParametersCodecs)7974 TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersCodecs) {
7975 AddRecvStream();
7976 cricket::VideoRecvParameters parameters;
7977 parameters.codecs.push_back(GetEngineCodec("VP8"));
7978 parameters.codecs.push_back(GetEngineCodec("VP9"));
7979 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
7980
7981 webrtc::RtpParameters rtp_parameters =
7982 channel_->GetRtpReceiveParameters(last_ssrc_);
7983 ASSERT_EQ(2u, rtp_parameters.codecs.size());
7984 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
7985 rtp_parameters.codecs[0]);
7986 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
7987 rtp_parameters.codecs[1]);
7988 }
7989
7990 #if defined(WEBRTC_USE_H264)
TEST_F(WebRtcVideoChannelTest,GetRtpReceiveFmtpSprop)7991 TEST_F(WebRtcVideoChannelTest, GetRtpReceiveFmtpSprop) {
7992 #else
7993 TEST_F(WebRtcVideoChannelTest, DISABLED_GetRtpReceiveFmtpSprop) {
7994 #endif
7995 cricket::VideoRecvParameters parameters;
7996 cricket::VideoCodec kH264sprop1(101, "H264");
7997 kH264sprop1.SetParam(kH264FmtpSpropParameterSets, "uvw");
7998 parameters.codecs.push_back(kH264sprop1);
7999 cricket::VideoCodec kH264sprop2(102, "H264");
8000 kH264sprop2.SetParam(kH264FmtpSpropParameterSets, "xyz");
8001 parameters.codecs.push_back(kH264sprop2);
8002 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
8003
8004 FakeVideoReceiveStream* recv_stream = AddRecvStream();
8005 const webrtc::VideoReceiveStream::Config& cfg = recv_stream->GetConfig();
8006 webrtc::RtpParameters rtp_parameters =
8007 channel_->GetRtpReceiveParameters(last_ssrc_);
8008 ASSERT_EQ(2u, rtp_parameters.codecs.size());
8009 EXPECT_EQ(kH264sprop1.ToCodecParameters(), rtp_parameters.codecs[0]);
8010 ASSERT_EQ(2u, cfg.decoders.size());
8011 EXPECT_EQ(101, cfg.decoders[0].payload_type);
8012 EXPECT_EQ("H264", cfg.decoders[0].video_format.name);
8013 const auto it0 =
8014 cfg.decoders[0].video_format.parameters.find(kH264FmtpSpropParameterSets);
8015 ASSERT_TRUE(it0 != cfg.decoders[0].video_format.parameters.end());
8016 EXPECT_EQ("uvw", it0->second);
8017
8018 EXPECT_EQ(102, cfg.decoders[1].payload_type);
8019 EXPECT_EQ("H264", cfg.decoders[1].video_format.name);
8020 const auto it1 =
8021 cfg.decoders[1].video_format.parameters.find(kH264FmtpSpropParameterSets);
8022 ASSERT_TRUE(it1 != cfg.decoders[1].video_format.parameters.end());
8023 EXPECT_EQ("xyz", it1->second);
8024 }
8025
8026 // Test that RtpParameters for receive stream has one encoding and it has
8027 // the correct SSRC.
8028 TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersSsrc) {
8029 AddRecvStream();
8030
8031 webrtc::RtpParameters rtp_parameters =
8032 channel_->GetRtpReceiveParameters(last_ssrc_);
8033 ASSERT_EQ(1u, rtp_parameters.encodings.size());
8034 EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc);
8035 }
8036
8037 // Test that if we set/get parameters multiple times, we get the same results.
8038 TEST_F(WebRtcVideoChannelTest, SetAndGetRtpReceiveParameters) {
8039 AddRecvStream();
8040 cricket::VideoRecvParameters parameters;
8041 parameters.codecs.push_back(GetEngineCodec("VP8"));
8042 parameters.codecs.push_back(GetEngineCodec("VP9"));
8043 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
8044
8045 webrtc::RtpParameters initial_params =
8046 channel_->GetRtpReceiveParameters(last_ssrc_);
8047
8048 // ... And this shouldn't change the params returned by
8049 // GetRtpReceiveParameters.
8050 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(last_ssrc_));
8051 }
8052
8053 // Test that GetDefaultRtpReceiveParameters returns parameters correctly when
8054 // SSRCs aren't signaled. It should always return an empty
8055 // "RtpEncodingParameters", even after a packet is received and the unsignaled
8056 // SSRC is known.
8057 TEST_F(WebRtcVideoChannelTest,
8058 GetDefaultRtpReceiveParametersWithUnsignaledSsrc) {
8059 // Call necessary methods to configure receiving a default stream as
8060 // soon as it arrives.
8061 cricket::VideoRecvParameters parameters;
8062 parameters.codecs.push_back(GetEngineCodec("VP8"));
8063 parameters.codecs.push_back(GetEngineCodec("VP9"));
8064 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
8065
8066 // Call GetRtpReceiveParameters before configured to receive an unsignaled
8067 // stream. Should return nothing.
8068 EXPECT_EQ(webrtc::RtpParameters(),
8069 channel_->GetDefaultRtpReceiveParameters());
8070
8071 // Set a sink for an unsignaled stream.
8072 cricket::FakeVideoRenderer renderer;
8073 channel_->SetDefaultSink(&renderer);
8074
8075 // Call GetDefaultRtpReceiveParameters before the SSRC is known.
8076 webrtc::RtpParameters rtp_parameters =
8077 channel_->GetDefaultRtpReceiveParameters();
8078 ASSERT_EQ(1u, rtp_parameters.encodings.size());
8079 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
8080
8081 // Receive VP8 packet.
8082 uint8_t data[kMinRtpPacketLen];
8083 cricket::RtpHeader rtpHeader;
8084 rtpHeader.payload_type = GetEngineCodec("VP8").id;
8085 rtpHeader.seq_num = rtpHeader.timestamp = 0;
8086 rtpHeader.ssrc = kIncomingUnsignalledSsrc;
8087 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
8088 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
8089 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
8090
8091 // The |ssrc| member should still be unset.
8092 rtp_parameters = channel_->GetDefaultRtpReceiveParameters();
8093 ASSERT_EQ(1u, rtp_parameters.encodings.size());
8094 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
8095 }
8096
8097 void WebRtcVideoChannelTest::TestReceiverLocalSsrcConfiguration(
8098 bool receiver_first) {
8099 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
8100
8101 const uint32_t kSenderSsrc = 0xC0FFEE;
8102 const uint32_t kSecondSenderSsrc = 0xBADCAFE;
8103 const uint32_t kReceiverSsrc = 0x4711;
8104 const uint32_t kExpectedDefaultReceiverSsrc = 1;
8105
8106 if (receiver_first) {
8107 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
8108 std::vector<FakeVideoReceiveStream*> receive_streams =
8109 fake_call_->GetVideoReceiveStreams();
8110 ASSERT_EQ(1u, receive_streams.size());
8111 // Default local SSRC when we have no sender.
8112 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
8113 receive_streams[0]->GetConfig().rtp.local_ssrc);
8114 }
8115 AddSendStream(StreamParams::CreateLegacy(kSenderSsrc));
8116 if (!receiver_first)
8117 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
8118 std::vector<FakeVideoReceiveStream*> receive_streams =
8119 fake_call_->GetVideoReceiveStreams();
8120 ASSERT_EQ(1u, receive_streams.size());
8121 EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
8122
8123 // Removing first sender should fall back to another (in this case the second)
8124 // local send stream's SSRC.
8125 AddSendStream(StreamParams::CreateLegacy(kSecondSenderSsrc));
8126 ASSERT_TRUE(channel_->RemoveSendStream(kSenderSsrc));
8127 receive_streams = fake_call_->GetVideoReceiveStreams();
8128 ASSERT_EQ(1u, receive_streams.size());
8129 EXPECT_EQ(kSecondSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
8130
8131 // Removing the last sender should fall back to default local SSRC.
8132 ASSERT_TRUE(channel_->RemoveSendStream(kSecondSenderSsrc));
8133 receive_streams = fake_call_->GetVideoReceiveStreams();
8134 ASSERT_EQ(1u, receive_streams.size());
8135 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
8136 receive_streams[0]->GetConfig().rtp.local_ssrc);
8137 }
8138
8139 TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrc) {
8140 TestReceiverLocalSsrcConfiguration(false);
8141 }
8142
8143 TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrcOnExistingReceivers) {
8144 TestReceiverLocalSsrcConfiguration(true);
8145 }
8146
8147 class WebRtcVideoChannelSimulcastTest : public ::testing::Test {
8148 public:
8149 WebRtcVideoChannelSimulcastTest()
8150 : fake_call_(),
8151 encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
8152 decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
8153 mock_rate_allocator_factory_(
8154 std::make_unique<webrtc::MockVideoBitrateAllocatorFactory>()),
8155 engine_(std::unique_ptr<cricket::FakeWebRtcVideoEncoderFactory>(
8156 encoder_factory_),
8157 std::unique_ptr<cricket::FakeWebRtcVideoDecoderFactory>(
8158 decoder_factory_)),
8159 last_ssrc_(0) {}
8160
8161 void SetUp() override {
8162 encoder_factory_->AddSupportedVideoCodecType("VP8");
8163 decoder_factory_->AddSupportedVideoCodecType("VP8");
8164 channel_.reset(engine_.CreateMediaChannel(
8165 &fake_call_, GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
8166 mock_rate_allocator_factory_.get()));
8167 channel_->OnReadyToSend(true);
8168 last_ssrc_ = 123;
8169 }
8170
8171 protected:
8172 void VerifySimulcastSettings(const VideoCodec& codec,
8173 int capture_width,
8174 int capture_height,
8175 size_t num_configured_streams,
8176 size_t expected_num_streams,
8177 bool screenshare,
8178 bool conference_mode) {
8179 cricket::VideoSendParameters parameters;
8180 parameters.codecs.push_back(codec);
8181 parameters.conference_mode = conference_mode;
8182 ASSERT_TRUE(channel_->SetSendParameters(parameters));
8183
8184 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
8185 RTC_DCHECK(num_configured_streams <= ssrcs.size());
8186 ssrcs.resize(num_configured_streams);
8187
8188 AddSendStream(CreateSimStreamParams("cname", ssrcs));
8189 // Send a full-size frame to trigger a stream reconfiguration to use all
8190 // expected simulcast layers.
8191 webrtc::test::FrameForwarder frame_forwarder;
8192 cricket::FakeFrameSource frame_source(capture_width, capture_height,
8193 rtc::kNumMicrosecsPerSec / 30);
8194
8195 VideoOptions options;
8196 if (screenshare)
8197 options.is_screencast = screenshare;
8198 EXPECT_TRUE(
8199 channel_->SetVideoSend(ssrcs.front(), &options, &frame_forwarder));
8200 // Fetch the latest stream since SetVideoSend() may recreate it if the
8201 // screen content setting is changed.
8202 FakeVideoSendStream* stream = fake_call_.GetVideoSendStreams().front();
8203 channel_->SetSend(true);
8204 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
8205
8206 auto rtp_parameters = channel_->GetRtpSendParameters(kSsrcs3[0]);
8207 EXPECT_EQ(num_configured_streams, rtp_parameters.encodings.size());
8208
8209 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
8210 ASSERT_EQ(expected_num_streams, video_streams.size());
8211 EXPECT_LE(expected_num_streams, stream->GetConfig().rtp.ssrcs.size());
8212
8213 std::vector<webrtc::VideoStream> expected_streams;
8214 if (num_configured_streams > 1 || conference_mode) {
8215 expected_streams = GetSimulcastConfig(
8216 /*min_layers=*/1, num_configured_streams, capture_width,
8217 capture_height, webrtc::kDefaultBitratePriority, kDefaultQpMax,
8218 screenshare && conference_mode, true);
8219 if (screenshare && conference_mode) {
8220 for (const webrtc::VideoStream& stream : expected_streams) {
8221 // Never scale screen content.
8222 EXPECT_EQ(stream.width, rtc::checked_cast<size_t>(capture_width));
8223 EXPECT_EQ(stream.height, rtc::checked_cast<size_t>(capture_height));
8224 }
8225 }
8226 } else {
8227 webrtc::VideoStream stream;
8228 stream.width = capture_width;
8229 stream.height = capture_height;
8230 stream.max_framerate = kDefaultVideoMaxFramerate;
8231 stream.min_bitrate_bps = webrtc::kDefaultMinVideoBitrateBps;
8232 stream.target_bitrate_bps = stream.max_bitrate_bps =
8233 GetMaxDefaultBitrateBps(capture_width, capture_height);
8234 stream.max_qp = kDefaultQpMax;
8235 expected_streams.push_back(stream);
8236 }
8237
8238 ASSERT_EQ(expected_streams.size(), video_streams.size());
8239
8240 size_t num_streams = video_streams.size();
8241 int total_max_bitrate_bps = 0;
8242 for (size_t i = 0; i < num_streams; ++i) {
8243 EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
8244 EXPECT_EQ(expected_streams[i].height, video_streams[i].height);
8245
8246 EXPECT_GT(video_streams[i].max_framerate, 0);
8247 EXPECT_EQ(expected_streams[i].max_framerate,
8248 video_streams[i].max_framerate);
8249
8250 EXPECT_GT(video_streams[i].min_bitrate_bps, 0);
8251 EXPECT_EQ(expected_streams[i].min_bitrate_bps,
8252 video_streams[i].min_bitrate_bps);
8253
8254 EXPECT_GT(video_streams[i].target_bitrate_bps, 0);
8255 EXPECT_EQ(expected_streams[i].target_bitrate_bps,
8256 video_streams[i].target_bitrate_bps);
8257
8258 EXPECT_GT(video_streams[i].max_bitrate_bps, 0);
8259 EXPECT_EQ(expected_streams[i].max_bitrate_bps,
8260 video_streams[i].max_bitrate_bps);
8261
8262 EXPECT_GT(video_streams[i].max_qp, 0);
8263 EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp);
8264
8265 EXPECT_EQ(num_configured_streams > 1 || conference_mode,
8266 expected_streams[i].num_temporal_layers.has_value());
8267
8268 if (conference_mode) {
8269 EXPECT_EQ(expected_streams[i].num_temporal_layers,
8270 video_streams[i].num_temporal_layers);
8271 }
8272
8273 if (i == num_streams - 1) {
8274 total_max_bitrate_bps += video_streams[i].max_bitrate_bps;
8275 } else {
8276 total_max_bitrate_bps += video_streams[i].target_bitrate_bps;
8277 }
8278 }
8279
8280 EXPECT_TRUE(channel_->SetVideoSend(ssrcs.front(), nullptr, nullptr));
8281 }
8282
8283 FakeVideoSendStream* AddSendStream() {
8284 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++));
8285 }
8286
8287 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
8288 size_t num_streams = fake_call_.GetVideoSendStreams().size();
8289 EXPECT_TRUE(channel_->AddSendStream(sp));
8290 std::vector<FakeVideoSendStream*> streams =
8291 fake_call_.GetVideoSendStreams();
8292 EXPECT_EQ(num_streams + 1, streams.size());
8293 return streams[streams.size() - 1];
8294 }
8295
8296 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
8297 return fake_call_.GetVideoSendStreams();
8298 }
8299
8300 FakeVideoReceiveStream* AddRecvStream() {
8301 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++));
8302 }
8303
8304 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
8305 size_t num_streams = fake_call_.GetVideoReceiveStreams().size();
8306 EXPECT_TRUE(channel_->AddRecvStream(sp));
8307 std::vector<FakeVideoReceiveStream*> streams =
8308 fake_call_.GetVideoReceiveStreams();
8309 EXPECT_EQ(num_streams + 1, streams.size());
8310 return streams[streams.size() - 1];
8311 }
8312
8313 webrtc::RtcEventLogNull event_log_;
8314 FakeCall fake_call_;
8315 cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
8316 cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
8317 std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
8318 mock_rate_allocator_factory_;
8319 WebRtcVideoEngine engine_;
8320 std::unique_ptr<VideoMediaChannel> channel_;
8321 uint32_t last_ssrc_;
8322 };
8323
8324 TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith2SimulcastStreams) {
8325 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 640, 360, 2, 2, false,
8326 true);
8327 }
8328
8329 TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith3SimulcastStreams) {
8330 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, false,
8331 true);
8332 }
8333
8334 // Test that we normalize send codec format size in simulcast.
8335 TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
8336 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 541, 271, 2, 2, false,
8337 true);
8338 }
8339
8340 TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForScreenshare) {
8341 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, true,
8342 false);
8343 }
8344
8345 TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForSimulcastScreenshare) {
8346 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 2, true,
8347 true);
8348 }
8349
8350 TEST_F(WebRtcVideoChannelSimulcastTest, SimulcastScreenshareWithoutConference) {
8351 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, true,
8352 false);
8353 }
8354
8355 TEST_F(WebRtcVideoChannelBaseTest, GetSources) {
8356 EXPECT_THAT(channel_->GetSources(kSsrc), IsEmpty());
8357
8358 channel_->SetDefaultSink(&renderer_);
8359 EXPECT_TRUE(SetDefaultCodec());
8360 EXPECT_TRUE(SetSend(true));
8361 EXPECT_EQ(renderer_.num_rendered_frames(), 0);
8362
8363 // Send and receive one frame.
8364 SendFrame();
8365 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
8366
8367 EXPECT_THAT(channel_->GetSources(kSsrc - 1), IsEmpty());
8368 EXPECT_THAT(channel_->GetSources(kSsrc), SizeIs(1));
8369 EXPECT_THAT(channel_->GetSources(kSsrc + 1), IsEmpty());
8370
8371 webrtc::RtpSource source = channel_->GetSources(kSsrc)[0];
8372 EXPECT_EQ(source.source_id(), kSsrc);
8373 EXPECT_EQ(source.source_type(), webrtc::RtpSourceType::SSRC);
8374 int64_t rtp_timestamp_1 = source.rtp_timestamp();
8375 int64_t timestamp_ms_1 = source.timestamp_ms();
8376
8377 // Send and receive another frame.
8378 SendFrame();
8379 EXPECT_FRAME_WAIT(2, kVideoWidth, kVideoHeight, kTimeout);
8380
8381 EXPECT_THAT(channel_->GetSources(kSsrc - 1), IsEmpty());
8382 EXPECT_THAT(channel_->GetSources(kSsrc), SizeIs(1));
8383 EXPECT_THAT(channel_->GetSources(kSsrc + 1), IsEmpty());
8384
8385 source = channel_->GetSources(kSsrc)[0];
8386 EXPECT_EQ(source.source_id(), kSsrc);
8387 EXPECT_EQ(source.source_type(), webrtc::RtpSourceType::SSRC);
8388 int64_t rtp_timestamp_2 = source.rtp_timestamp();
8389 int64_t timestamp_ms_2 = source.timestamp_ms();
8390
8391 EXPECT_GT(rtp_timestamp_2, rtp_timestamp_1);
8392 EXPECT_GT(timestamp_ms_2, timestamp_ms_1);
8393 }
8394
8395 TEST_F(WebRtcVideoChannelTest, SetsRidsOnSendStream) {
8396 StreamParams sp = CreateSimStreamParams("cname", {123, 456, 789});
8397
8398 std::vector<std::string> rids = {"f", "h", "q"};
8399 std::vector<cricket::RidDescription> rid_descriptions;
8400 for (const auto& rid : rids) {
8401 rid_descriptions.emplace_back(rid, cricket::RidDirection::kSend);
8402 }
8403 sp.set_rids(rid_descriptions);
8404
8405 ASSERT_TRUE(channel_->AddSendStream(sp));
8406 const auto& streams = fake_call_->GetVideoSendStreams();
8407 ASSERT_EQ(1u, streams.size());
8408 auto stream = streams[0];
8409 ASSERT_NE(stream, nullptr);
8410 const auto& config = stream->GetConfig();
8411 EXPECT_THAT(config.rtp.rids, ElementsAreArray(rids));
8412 }
8413
8414 } // namespace cricket
8415