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