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