blob: ad5b54b20f2b904b0b5c70bfd9c7bd12630a2f59 [file] [log] [blame]
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * 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.
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00009 */
10
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +000011#include <algorithm>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000012#include <map>
kwiberg686a8ef2016-02-26 03:00:35 -080013#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070014#include <utility>
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000015#include <vector>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000016
Niels Möller805a27e2019-01-21 12:21:27 +010017#include "absl/memory/memory.h"
Niels Möller039743e2018-10-23 10:07:25 +020018#include "absl/strings/match.h"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "api/rtp_parameters.h"
Jiawei Ouc2ebe212018-11-08 10:02:56 -080020#include "api/test/mock_video_bitrate_allocator.h"
21#include "api/test/mock_video_bitrate_allocator_factory.h"
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -070022#include "api/test/mock_video_decoder_factory.h"
23#include "api/test/mock_video_encoder_factory.h"
Jonas Oreland49ac5952018-09-26 16:04:32 +020024#include "api/units/time_delta.h"
Jiawei Ouc2ebe212018-11-08 10:02:56 -080025#include "api/video/builtin_video_bitrate_allocator_factory.h"
Niels Möller805a27e2019-01-21 12:21:27 +010026#include "api/video/i420_buffer.h"
Åsa Persson23eba222018-10-02 14:47:06 +020027#include "api/video/video_bitrate_allocation.h"
Anders Carlsson5f2bb622018-05-14 09:48:06 +020028#include "api/video_codecs/builtin_video_decoder_factory.h"
29#include "api/video_codecs/builtin_video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020030#include "api/video_codecs/sdp_video_format.h"
31#include "api/video_codecs/video_decoder_factory.h"
32#include "api/video_codecs/video_encoder.h"
33#include "api/video_codecs/video_encoder_factory.h"
34#include "call/flexfec_receive_stream.h"
35#include "common_video/h264/profile_level_id.h"
36#include "logging/rtc_event_log/rtc_event_log.h"
Niels Möller805a27e2019-01-21 12:21:27 +010037#include "media/base/fake_frame_source.h"
Steve Anton10542f22019-01-11 09:11:00 -080038#include "media/base/fake_network_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080039#include "media/base/fake_video_renderer.h"
40#include "media/base/media_constants.h"
41#include "media/base/rtp_utils.h"
42#include "media/base/test_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020043#include "media/engine/constants.h"
Steve Anton10542f22019-01-11 09:11:00 -080044#include "media/engine/fake_webrtc_call.h"
45#include "media/engine/fake_webrtc_video_engine.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020046#include "media/engine/simulcast.h"
Steve Anton10542f22019-01-11 09:11:00 -080047#include "media/engine/webrtc_video_engine.h"
48#include "media/engine/webrtc_voice_engine.h"
Åsa Persson23cd45a2018-07-03 10:40:40 +020049#include "modules/rtp_rtcp/include/rtp_header_parser.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020050#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080051#include "rtc_base/fake_clock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020052#include "rtc_base/gunit.h"
Yves Gerey665174f2018-06-19 15:03:05 +020053#include "rtc_base/numerics/safe_conversions.h"
Niels Möllerd0f0f682019-01-14 09:09:53 +010054#include "rtc_base/timeutils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020055#include "test/field_trial.h"
Niels Möllerd0f0f682019-01-14 09:09:53 +010056#include "test/frame_generator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020057#include "test/gmock.h"
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000058
Niels Möller805a27e2019-01-21 12:21:27 +010059using testing::Field;
Sebastian Jansson8f83b422018-02-21 13:07:13 +010060using webrtc::BitrateConstraints;
isheriff6f8d6862016-05-26 11:24:55 -070061using webrtc::RtpExtension;
62
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000063namespace {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000064static const int kDefaultQpMax = 56;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000065
noahricd10a68e2015-07-10 11:27:55 -070066static const uint8_t kRedRtxPayloadType = 125;
67
Niels Möller6557d0c2018-04-11 15:18:34 +020068static const uint32_t kTimeout = 5000U;
69static const uint32_t kDefaultReceiveSsrc = 0;
70static const uint32_t kSsrc = 1234u;
71static const uint32_t kSsrcs4[] = {1, 2, 3, 4};
72static const int kVideoWidth = 640;
73static const int kVideoHeight = 360;
74static const int kFramerate = 30;
75
Peter Boström0c4e06b2015-10-07 12:23:21 +020076static const uint32_t kSsrcs1[] = {1};
77static const uint32_t kSsrcs3[] = {1, 2, 3};
78static const uint32_t kRtxSsrcs1[] = {4};
brandtr468da7c2016-11-22 02:16:47 -080079static const uint32_t kFlexfecSsrc = 5;
Peter Boström0c4e06b2015-10-07 12:23:21 +020080static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE;
mzanaty8a855d62017-02-17 15:46:43 -080081static const uint32_t kDefaultRecvSsrc = 0;
82
pbos@webrtc.org3c107582014-07-20 15:27:35 +000083static const char kUnsupportedExtensionName[] =
84 "urn:ietf:params:rtp-hdrext:unsupported";
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000085
magjed509e4fe2016-11-18 01:34:11 -080086cricket::VideoCodec RemoveFeedbackParams(cricket::VideoCodec&& codec) {
87 codec.feedback_params = cricket::FeedbackParams();
Mirko Bonadei29a8d102018-04-25 23:58:26 +020088 return std::move(codec);
magjed509e4fe2016-11-18 01:34:11 -080089}
90
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000091void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) {
92 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
93 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
94 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
95 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
96 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
97 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
98 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
stefan43edf0f2015-11-20 18:05:48 -080099 cricket::kRtcpFbParamTransportCc, cricket::kParamValueEmpty)));
100 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +0000101 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
102}
103
magjed725e4842016-11-16 00:48:13 -0800104// Return true if any codec in |codecs| is an RTX codec with associated payload
105// type |payload_type|.
106bool HasRtxCodec(const std::vector<cricket::VideoCodec>& codecs,
107 int payload_type) {
108 for (const cricket::VideoCodec& codec : codecs) {
109 int associated_payload_type;
Niels Möller039743e2018-10-23 10:07:25 +0200110 if (absl::EqualsIgnoreCase(codec.name.c_str(), "rtx") &&
magjed725e4842016-11-16 00:48:13 -0800111 codec.GetParam(cricket::kCodecParamAssociatedPayloadType,
112 &associated_payload_type) &&
113 associated_payload_type == payload_type) {
114 return true;
115 }
116 }
117 return false;
118}
119
nisseca5706d2017-09-11 02:32:16 -0700120// TODO(nisse): Duplicated in call.cc.
121const int* FindKeyByValue(const std::map<int, int>& m, int v) {
122 for (const auto& kv : m) {
123 if (kv.second == v)
124 return &kv.first;
125 }
126 return nullptr;
127}
128
Yves Gerey665174f2018-06-19 15:03:05 +0200129bool HasRtxReceiveAssociation(const webrtc::VideoReceiveStream::Config& config,
130 int payload_type) {
nisseca5706d2017-09-11 02:32:16 -0700131 return FindKeyByValue(config.rtp.rtx_associated_payload_types,
132 payload_type) != nullptr;
133}
134
135// Check that there's an Rtx payload type for each decoder.
136bool VerifyRtxReceiveAssociations(
137 const webrtc::VideoReceiveStream::Config& config) {
138 for (const auto& decoder : config.decoders) {
139 if (!HasRtxReceiveAssociation(config, decoder.payload_type))
140 return false;
141 }
142 return true;
143}
144
brandtrffc61182016-11-28 06:02:22 -0800145rtc::scoped_refptr<webrtc::VideoFrameBuffer> CreateBlackFrameBuffer(
nisse64ec8f82016-09-27 00:17:25 -0700146 int width,
147 int height) {
148 rtc::scoped_refptr<webrtc::I420Buffer> buffer =
149 webrtc::I420Buffer::Create(width, height);
nisseaf916892017-01-10 07:44:26 -0800150 webrtc::I420Buffer::SetBlack(buffer);
nisse64ec8f82016-09-27 00:17:25 -0700151 return buffer;
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +0000152}
153
Shao Changbine62202f2015-04-21 20:24:50 +0800154void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config,
155 const std::map<int, int>& rtx_types) {
156 std::map<int, int>::const_iterator it;
Niels Möller259a4972018-04-05 15:36:51 +0200157 it = rtx_types.find(config.rtp.payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800158 EXPECT_TRUE(it != rtx_types.end() &&
159 it->second == config.rtp.rtx.payload_type);
160
brandtrb5f2c3f2016-10-04 23:28:39 -0700161 if (config.rtp.ulpfec.red_rtx_payload_type != -1) {
162 it = rtx_types.find(config.rtp.ulpfec.red_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800163 EXPECT_TRUE(it != rtx_types.end() &&
brandtrb5f2c3f2016-10-04 23:28:39 -0700164 it->second == config.rtp.ulpfec.red_rtx_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800165 }
166}
kthelgason2bc68642017-02-07 07:02:22 -0800167
168cricket::MediaConfig GetMediaConfig() {
169 cricket::MediaConfig media_config;
Niels Möller1d7ecd22018-01-18 15:25:12 +0100170 media_config.video.enable_cpu_adaptation = false;
kthelgason2bc68642017-02-07 07:02:22 -0800171 return media_config;
172}
nisse26e3abb2017-08-25 04:44:25 -0700173
Åsa Perssonbdee46d2018-06-25 11:28:06 +0200174// Values from GetMaxDefaultVideoBitrateKbps in webrtcvideoengine.cc.
175int GetMaxDefaultBitrateBps(size_t width, size_t height) {
176 if (width * height <= 320 * 240) {
177 return 600000;
178 } else if (width * height <= 640 * 480) {
179 return 1700000;
180 } else if (width * height <= 960 * 540) {
181 return 2000000;
182 } else {
183 return 2500000;
184 }
185}
186
Niels Möller731a2c22018-07-30 15:08:07 +0200187class MockVideoSource : public rtc::VideoSourceInterface<webrtc::VideoFrame> {
188 public:
189 MOCK_METHOD2(AddOrUpdateSink,
190 void(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink,
191 const rtc::VideoSinkWants& wants));
192 MOCK_METHOD1(RemoveSink,
193 void(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink));
194};
195
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000196} // namespace
197
Yves Gerey665174f2018-06-19 15:03:05 +0200198#define EXPECT_FRAME_WAIT(c, w, h, t) \
Niels Möller6557d0c2018-04-11 15:18:34 +0200199 EXPECT_EQ_WAIT((c), renderer_.num_rendered_frames(), (t)); \
Yves Gerey665174f2018-06-19 15:03:05 +0200200 EXPECT_EQ((w), renderer_.width()); \
201 EXPECT_EQ((h), renderer_.height()); \
Niels Möller6557d0c2018-04-11 15:18:34 +0200202 EXPECT_EQ(0, renderer_.errors());
203
Yves Gerey665174f2018-06-19 15:03:05 +0200204#define EXPECT_FRAME_ON_RENDERER_WAIT(r, c, w, h, t) \
Niels Möller6557d0c2018-04-11 15:18:34 +0200205 EXPECT_EQ_WAIT((c), (r).num_rendered_frames(), (t)); \
Yves Gerey665174f2018-06-19 15:03:05 +0200206 EXPECT_EQ((w), (r).width()); \
207 EXPECT_EQ((h), (r).height()); \
Niels Möller6557d0c2018-04-11 15:18:34 +0200208 EXPECT_EQ(0, (r).errors());
209
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000210namespace cricket {
eladalonf1841382017-06-12 01:16:46 -0700211class WebRtcVideoEngineTest : public ::testing::Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000212 public:
eladalonf1841382017-06-12 01:16:46 -0700213 WebRtcVideoEngineTest() : WebRtcVideoEngineTest("") {}
214 explicit WebRtcVideoEngineTest(const char* field_trials)
stefanc1aeaf02015-10-15 07:26:07 -0700215 : override_field_trials_(field_trials),
skvlad11a9cbf2016-10-07 11:53:05 -0700216 call_(webrtc::Call::Create(webrtc::Call::Config(&event_log_))),
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200217 encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
218 decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
Anders Carlsson67537952018-05-03 11:28:29 +0200219 engine_(std::unique_ptr<cricket::FakeWebRtcVideoEncoderFactory>(
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200220 encoder_factory_),
Anders Carlsson67537952018-05-03 11:28:29 +0200221 std::unique_ptr<cricket::FakeWebRtcVideoDecoderFactory>(
Jiawei Ouc2ebe212018-11-08 10:02:56 -0800222 decoder_factory_),
223 webrtc::CreateBuiltinVideoBitrateAllocatorFactory()) {
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +0200224 // Ensure fake clock doesn't return 0, which will cause some initializations
225 // fail inside RTP senders.
226 fake_clock_.AdvanceTimeMicros(1);
227 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000228
229 protected:
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200230 void AssignDefaultAptRtxTypes();
231 void AssignDefaultCodec();
232
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100233 // Find the index of the codec in the engine with the given name. The codec
234 // must be present.
Oleh Prypina40f8242017-12-21 13:32:23 +0100235 size_t GetEngineCodecIndex(const std::string& name) const;
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100236
magjed509e4fe2016-11-18 01:34:11 -0800237 // Find the codec in the engine with the given name. The codec must be
238 // present.
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100239 cricket::VideoCodec GetEngineCodec(const std::string& name) const;
magjed509e4fe2016-11-18 01:34:11 -0800240
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200241 VideoMediaChannel* SetSendParamsWithAllSupportedCodecs();
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000242
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200243 VideoMediaChannel* SetRecvParamsWithSupportedCodecs(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000244 const std::vector<VideoCodec>& codecs);
245
Peter Boströme4499152016-02-05 11:13:28 +0100246 void TestExtendedEncoderOveruse(bool use_external_encoder);
247
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +0200248 // Has to be the first one, so it is initialized before the call or there is a
249 // race condition in the clock access.
250 rtc::ScopedFakeClock fake_clock_;
stefanc1aeaf02015-10-15 07:26:07 -0700251 webrtc::test::ScopedFieldTrials override_field_trials_;
skvlad11a9cbf2016-10-07 11:53:05 -0700252 webrtc::RtcEventLogNullImpl event_log_;
eladalonf1841382017-06-12 01:16:46 -0700253 // Used in WebRtcVideoEngineVoiceTest, but defined here so it's properly
pbos@webrtc.orgf1f0d9a2015-03-02 13:30:15 +0000254 // initialized when the constructor is called.
kwiberg686a8ef2016-02-26 03:00:35 -0800255 std::unique_ptr<webrtc::Call> call_;
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200256 cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
257 cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
eladalonf1841382017-06-12 01:16:46 -0700258 WebRtcVideoEngine engine_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000259 VideoCodec default_codec_;
Shao Changbine62202f2015-04-21 20:24:50 +0800260 std::map<int, int> default_apt_rtx_types_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000261};
262
eladalonf1841382017-06-12 01:16:46 -0700263TEST_F(WebRtcVideoEngineTest, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200264 encoder_factory_->AddSupportedVideoCodecType("VP8");
265 AssignDefaultCodec();
266
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000267 std::vector<VideoCodec> engine_codecs = engine_.codecs();
268 for (size_t i = 0; i < engine_codecs.size(); ++i) {
269 if (engine_codecs[i].name != kRtxCodecName)
270 continue;
271 int associated_payload_type;
272 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000273 &associated_payload_type));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000274 EXPECT_EQ(default_codec_.id, associated_payload_type);
275 return;
276 }
277 FAIL() << "No RTX codec found among default codecs.";
278}
279
eladalonf1841382017-06-12 01:16:46 -0700280TEST_F(WebRtcVideoEngineTest, SupportsTimestampOffsetHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100281 RtpCapabilities capabilities = engine_.GetCapabilities();
Johannes Krond0b69a82018-12-03 14:18:53 +0100282 EXPECT_THAT(
283 capabilities.header_extensions,
284 testing::Contains(RtpExtension(RtpExtension::kTimestampOffsetUri,
285 RtpExtension::kTimestampOffsetDefaultId)));
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000286}
287
eladalonf1841382017-06-12 01:16:46 -0700288TEST_F(WebRtcVideoEngineTest, SupportsAbsoluteSenderTimeHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100289 RtpCapabilities capabilities = engine_.GetCapabilities();
Johannes Krond0b69a82018-12-03 14:18:53 +0100290 EXPECT_THAT(
291 capabilities.header_extensions,
292 testing::Contains(RtpExtension(RtpExtension::kAbsSendTimeUri,
293 RtpExtension::kAbsSendTimeDefaultId)));
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000294}
295
eladalonf1841382017-06-12 01:16:46 -0700296TEST_F(WebRtcVideoEngineTest, SupportsTransportSequenceNumberHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100297 RtpCapabilities capabilities = engine_.GetCapabilities();
Johannes Krond0b69a82018-12-03 14:18:53 +0100298 EXPECT_THAT(capabilities.header_extensions,
299 testing::Contains(RtpExtension(
300 RtpExtension::kTransportSequenceNumberUri,
301 RtpExtension::kTransportSequenceNumberDefaultId)));
stefanc1aeaf02015-10-15 07:26:07 -0700302}
303
eladalonf1841382017-06-12 01:16:46 -0700304TEST_F(WebRtcVideoEngineTest, SupportsVideoRotationHeaderExtension) {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100305 RtpCapabilities capabilities = engine_.GetCapabilities();
Johannes Krond0b69a82018-12-03 14:18:53 +0100306 EXPECT_THAT(
307 capabilities.header_extensions,
308 testing::Contains(RtpExtension(RtpExtension::kVideoRotationUri,
309 RtpExtension::kVideoRotationDefaultId)));
310}
311
312TEST_F(WebRtcVideoEngineTest, SupportsColorSpaceHeaderExtension) {
313 RtpCapabilities capabilities = engine_.GetCapabilities();
314 EXPECT_THAT(
315 capabilities.header_extensions,
316 testing::Contains(RtpExtension(RtpExtension::kColorSpaceUri,
317 RtpExtension::kColorSpaceDefaultId)));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700318}
319
philipel1e054862018-10-08 16:13:53 +0200320class WebRtcVideoEngineTestWithGenericDescriptor
321 : public WebRtcVideoEngineTest {
322 public:
323 WebRtcVideoEngineTestWithGenericDescriptor()
324 : WebRtcVideoEngineTest("WebRTC-GenericDescriptorAdvertised/Enabled/") {}
325};
326
327TEST_F(WebRtcVideoEngineTestWithGenericDescriptor, AdvertiseGenericDescriptor) {
328 RtpCapabilities capabilities = engine_.GetCapabilities();
329 ASSERT_FALSE(capabilities.header_extensions.empty());
330 for (const RtpExtension& extension : capabilities.header_extensions) {
331 if (extension.uri == RtpExtension::kGenericFrameDescriptorUri) {
332 EXPECT_EQ(RtpExtension::kGenericFrameDescriptorDefaultId, extension.id);
333 return;
334 }
335 }
336 FAIL() << "Generic descriptor extension not in header-extension list.";
337}
338
eladalonf1841382017-06-12 01:16:46 -0700339TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeCapturer) {
Niels Möller731a2c22018-07-30 15:08:07 +0200340 // Allocate the source first to prevent early destruction before channel's
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700341 // dtor is called.
Niels Möller731a2c22018-07-30 15:08:07 +0200342 testing::NiceMock<MockVideoSource> video_source;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700343
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200344 encoder_factory_->AddSupportedVideoCodecType("VP8");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700345
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200346 std::unique_ptr<VideoMediaChannel> channel(
347 SetSendParamsWithAllSupportedCodecs());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700348 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
349
350 // Add CVO extension.
351 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800352 cricket::VideoSendParameters parameters;
353 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200354 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700355 RtpExtension(RtpExtension::kVideoRotationUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200356 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700357
Niels Möller731a2c22018-07-30 15:08:07 +0200358 EXPECT_CALL(
359 video_source,
360 AddOrUpdateSink(testing::_,
361 Field(&rtc::VideoSinkWants::rotation_applied, false)));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700362 // Set capturer.
Niels Möller731a2c22018-07-30 15:08:07 +0200363 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700364
365 // Verify capturer has turned off applying rotation.
Niels Möller731a2c22018-07-30 15:08:07 +0200366 testing::Mock::VerifyAndClear(&video_source);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700367
368 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200369 parameters.extensions.clear();
Niels Möller731a2c22018-07-30 15:08:07 +0200370 EXPECT_CALL(
371 video_source,
372 AddOrUpdateSink(testing::_,
373 Field(&rtc::VideoSinkWants::rotation_applied, true)));
374
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200375 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700376}
377
eladalonf1841382017-06-12 01:16:46 -0700378TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeAddSendStream) {
Niels Möller731a2c22018-07-30 15:08:07 +0200379 // Allocate the source first to prevent early destruction before channel's
perkj91e1c152016-03-02 05:34:00 -0800380 // dtor is called.
Niels Möller731a2c22018-07-30 15:08:07 +0200381 testing::NiceMock<MockVideoSource> video_source;
perkj91e1c152016-03-02 05:34:00 -0800382
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200383 encoder_factory_->AddSupportedVideoCodecType("VP8");
perkj91e1c152016-03-02 05:34:00 -0800384
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200385 std::unique_ptr<VideoMediaChannel> channel(
386 SetSendParamsWithAllSupportedCodecs());
perkj91e1c152016-03-02 05:34:00 -0800387 // Add CVO extension.
388 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800389 cricket::VideoSendParameters parameters;
390 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj91e1c152016-03-02 05:34:00 -0800391 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700392 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkj91e1c152016-03-02 05:34:00 -0800393 EXPECT_TRUE(channel->SetSendParameters(parameters));
394 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
395
Niels Möller731a2c22018-07-30 15:08:07 +0200396 // Set source.
397 EXPECT_CALL(
398 video_source,
399 AddOrUpdateSink(testing::_,
400 Field(&rtc::VideoSinkWants::rotation_applied, false)));
401 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
perkj91e1c152016-03-02 05:34:00 -0800402}
403
eladalonf1841382017-06-12 01:16:46 -0700404TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionAfterCapturer) {
Niels Möller731a2c22018-07-30 15:08:07 +0200405 testing::NiceMock<MockVideoSource> video_source;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700406
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200407 encoder_factory_->AddSupportedVideoCodecType("VP8");
408 encoder_factory_->AddSupportedVideoCodecType("VP9");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700409
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200410 std::unique_ptr<VideoMediaChannel> channel(
411 SetSendParamsWithAllSupportedCodecs());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700412 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
413
414 // Set capturer.
Niels Möller731a2c22018-07-30 15:08:07 +0200415 EXPECT_CALL(
416 video_source,
417 AddOrUpdateSink(testing::_,
418 Field(&rtc::VideoSinkWants::rotation_applied, true)));
419 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700420
perkjcaafdba2016-03-20 07:34:29 -0700421 // Verify capturer has turned on applying rotation.
Niels Möller731a2c22018-07-30 15:08:07 +0200422 testing::Mock::VerifyAndClear(&video_source);
perkjcaafdba2016-03-20 07:34:29 -0700423
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700424 // Add CVO extension.
425 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800426 cricket::VideoSendParameters parameters;
427 parameters.codecs.push_back(GetEngineCodec("VP8"));
428 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200429 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700430 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkjcaafdba2016-03-20 07:34:29 -0700431 // Also remove the first codec to trigger a codec change as well.
432 parameters.codecs.erase(parameters.codecs.begin());
Niels Möller731a2c22018-07-30 15:08:07 +0200433 EXPECT_CALL(
434 video_source,
435 AddOrUpdateSink(testing::_,
436 Field(&rtc::VideoSinkWants::rotation_applied, false)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200437 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700438
439 // Verify capturer has turned off applying rotation.
Niels Möller731a2c22018-07-30 15:08:07 +0200440 testing::Mock::VerifyAndClear(&video_source);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700441
442 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200443 parameters.extensions.clear();
Niels Möller731a2c22018-07-30 15:08:07 +0200444 EXPECT_CALL(
445 video_source,
446 AddOrUpdateSink(testing::_,
447 Field(&rtc::VideoSinkWants::rotation_applied, true)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200448 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700449}
450
eladalonf1841382017-06-12 01:16:46 -0700451TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200452 encoder_factory_->AddSupportedVideoCodecType("VP8");
453
Sebastian Jansson84848f22018-11-16 10:40:36 +0100454 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700455 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000456
457 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
458
459 EXPECT_FALSE(channel->SetSend(true))
460 << "Channel should not start without codecs.";
461 EXPECT_TRUE(channel->SetSend(false))
462 << "Channel should be stoppable even without set codecs.";
463}
464
eladalonf1841382017-06-12 01:16:46 -0700465TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200466 encoder_factory_->AddSupportedVideoCodecType("VP8");
467
Sebastian Jansson84848f22018-11-16 10:40:36 +0100468 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700469 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000470 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
471 VideoMediaInfo info;
472 channel->GetStats(&info);
473}
474
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200475TEST_F(WebRtcVideoEngineTest, UseFactoryForVp8WhenSupported) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200476 encoder_factory_->AddSupportedVideoCodecType("VP8");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000477
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200478 std::unique_ptr<VideoMediaChannel> channel(
479 SetSendParamsWithAllSupportedCodecs());
Sergey Ulanove2b15012016-11-22 16:08:30 -0800480 channel->OnReadyToSend(true);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000481
482 EXPECT_TRUE(
483 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200484 EXPECT_EQ(0, encoder_factory_->GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000485 EXPECT_TRUE(channel->SetSend(true));
Niels Möllerd0f0f682019-01-14 09:09:53 +0100486 webrtc::test::FrameForwarder frame_forwarder;
487 cricket::FakeFrameSource frame_source(1280, 720,
488 rtc::kNumMicrosecsPerSec / 30);
489 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
490 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Per21d45d22016-10-30 21:37:57 +0100491 // Sending one frame will have allocate the encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200492 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
493 EXPECT_TRUE_WAIT(encoder_factory_->encoders()[0]->GetNumEncodedFrames() > 0,
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000494 kTimeout);
495
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200496 int num_created_encoders = encoder_factory_->GetNumCreatedEncoders();
Per21d45d22016-10-30 21:37:57 +0100497 EXPECT_EQ(num_created_encoders, 1);
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000498
499 // Setting codecs of the same type should not reallocate any encoders
500 // (expecting a no-op).
magjed509e4fe2016-11-18 01:34:11 -0800501 cricket::VideoSendParameters parameters;
502 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200503 EXPECT_TRUE(channel->SetSendParameters(parameters));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200504 EXPECT_EQ(num_created_encoders, encoder_factory_->GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000505
506 // Remove stream previously added to free the external encoder instance.
507 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200508 EXPECT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000509}
510
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200511// Test that when an encoder factory supports H264, we add an RTX
512// codec for it.
513// TODO(deadbeef): This test should be updated if/when we start
514// adding RTX codecs for unrecognized codec names.
515TEST_F(WebRtcVideoEngineTest, RtxCodecAddedForH264Codec) {
magjed725e4842016-11-16 00:48:13 -0800516 using webrtc::H264::ProfileLevelIdToString;
517 using webrtc::H264::ProfileLevelId;
518 using webrtc::H264::kLevel1;
Anders Carlsson67537952018-05-03 11:28:29 +0200519 webrtc::SdpVideoFormat h264_constrained_baseline("H264");
520 h264_constrained_baseline.parameters[kH264FmtpProfileLevelId] =
magjed725e4842016-11-16 00:48:13 -0800521 *ProfileLevelIdToString(
522 ProfileLevelId(webrtc::H264::kProfileConstrainedBaseline, kLevel1));
Anders Carlsson67537952018-05-03 11:28:29 +0200523 webrtc::SdpVideoFormat h264_constrained_high("H264");
524 h264_constrained_high.parameters[kH264FmtpProfileLevelId] =
magjed725e4842016-11-16 00:48:13 -0800525 *ProfileLevelIdToString(
526 ProfileLevelId(webrtc::H264::kProfileConstrainedHigh, kLevel1));
Anders Carlsson67537952018-05-03 11:28:29 +0200527 webrtc::SdpVideoFormat h264_high("H264");
528 h264_high.parameters[kH264FmtpProfileLevelId] = *ProfileLevelIdToString(
magjed725e4842016-11-16 00:48:13 -0800529 ProfileLevelId(webrtc::H264::kProfileHigh, kLevel1));
530
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200531 encoder_factory_->AddSupportedVideoCodec(h264_constrained_baseline);
532 encoder_factory_->AddSupportedVideoCodec(h264_constrained_high);
533 encoder_factory_->AddSupportedVideoCodec(h264_high);
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700534
magjed725e4842016-11-16 00:48:13 -0800535 // First figure out what payload types the test codecs got assigned.
536 const std::vector<cricket::VideoCodec> codecs = engine_.codecs();
magjed509e4fe2016-11-18 01:34:11 -0800537 // Now search for RTX codecs for them. Expect that they all have associated
538 // RTX codecs.
magjed725e4842016-11-16 00:48:13 -0800539 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200540 codecs,
541 FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_baseline))
542 ->id));
magjed725e4842016-11-16 00:48:13 -0800543 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200544 codecs,
545 FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_high))
546 ->id));
magjed509e4fe2016-11-18 01:34:11 -0800547 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200548 codecs, FindMatchingCodec(codecs, cricket::VideoCodec(h264_high))->id));
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700549}
550
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100551#if defined(RTC_ENABLE_VP9)
eladalonf1841382017-06-12 01:16:46 -0700552TEST_F(WebRtcVideoEngineTest, CanConstructDecoderForVp9EncoderFactory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200553 encoder_factory_->AddSupportedVideoCodecType("VP9");
Peter Boström53eda3d2015-03-27 15:53:18 +0100554
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200555 std::unique_ptr<VideoMediaChannel> channel(
556 SetSendParamsWithAllSupportedCodecs());
Peter Boström53eda3d2015-03-27 15:53:18 +0100557
558 EXPECT_TRUE(
559 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
560}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100561#endif // defined(RTC_ENABLE_VP9)
Peter Boström53eda3d2015-03-27 15:53:18 +0100562
eladalonf1841382017-06-12 01:16:46 -0700563TEST_F(WebRtcVideoEngineTest, PropagatesInputFrameTimestamp) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200564 encoder_factory_->AddSupportedVideoCodecType("VP8");
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100565 FakeCall* fake_call = new FakeCall();
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200566 call_.reset(fake_call);
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200567 std::unique_ptr<VideoMediaChannel> channel(
568 SetSendParamsWithAllSupportedCodecs());
qiangchenc27d89f2015-07-16 10:27:16 -0700569
570 EXPECT_TRUE(
571 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
572
Niels Möllerd0f0f682019-01-14 09:09:53 +0100573 webrtc::test::FrameForwarder frame_forwarder;
574 cricket::FakeFrameSource frame_source(1280, 720,
575 rtc::kNumMicrosecsPerSec / 60);
576 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
qiangchenc27d89f2015-07-16 10:27:16 -0700577 channel->SetSend(true);
578
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200579 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
qiangchenc27d89f2015-07-16 10:27:16 -0700580
Niels Möllerd0f0f682019-01-14 09:09:53 +0100581 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos1cb121d2015-09-14 11:38:38 -0700582 int64_t last_timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700583 for (int i = 0; i < 10; i++) {
Niels Möllerd0f0f682019-01-14 09:09:53 +0100584 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos1cb121d2015-09-14 11:38:38 -0700585 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700586 int64_t interval = timestamp - last_timestamp;
587
588 // Precision changes from nanosecond to millisecond.
589 // Allow error to be no more than 1.
590 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1);
591
592 last_timestamp = timestamp;
593 }
594
Niels Möllerd0f0f682019-01-14 09:09:53 +0100595 frame_forwarder.IncomingCapturedFrame(
596 frame_source.GetFrame(1280, 720, webrtc::VideoRotation::kVideoRotation_0,
597 rtc::kNumMicrosecsPerSec / 30));
qiangchenc27d89f2015-07-16 10:27:16 -0700598 last_timestamp = stream->GetLastTimestamp();
599 for (int i = 0; i < 10; i++) {
Niels Möllerd0f0f682019-01-14 09:09:53 +0100600 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame(
601 1280, 720, webrtc::VideoRotation::kVideoRotation_0,
602 rtc::kNumMicrosecsPerSec / 30));
pbos1cb121d2015-09-14 11:38:38 -0700603 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700604 int64_t interval = timestamp - last_timestamp;
605
606 // Precision changes from nanosecond to millisecond.
607 // Allow error to be no more than 1.
608 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1);
609
610 last_timestamp = timestamp;
611 }
612
613 // Remove stream previously added to free the external encoder instance.
614 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
615}
616
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200617void WebRtcVideoEngineTest::AssignDefaultAptRtxTypes() {
618 std::vector<VideoCodec> engine_codecs = engine_.codecs();
619 RTC_DCHECK(!engine_codecs.empty());
620 for (const cricket::VideoCodec& codec : engine_codecs) {
621 if (codec.name == "rtx") {
622 int associated_payload_type;
623 if (codec.GetParam(kCodecParamAssociatedPayloadType,
624 &associated_payload_type)) {
625 default_apt_rtx_types_[associated_payload_type] = codec.id;
626 }
627 }
628 }
629}
630
631void WebRtcVideoEngineTest::AssignDefaultCodec() {
632 std::vector<VideoCodec> engine_codecs = engine_.codecs();
633 RTC_DCHECK(!engine_codecs.empty());
634 bool codec_set = false;
635 for (const cricket::VideoCodec& codec : engine_codecs) {
636 if (!codec_set && codec.name != "rtx" && codec.name != "red" &&
637 codec.name != "ulpfec") {
638 default_codec_ = codec;
639 codec_set = true;
640 }
641 }
642
643 RTC_DCHECK(codec_set);
644}
645
Oleh Prypina40f8242017-12-21 13:32:23 +0100646size_t WebRtcVideoEngineTest::GetEngineCodecIndex(
647 const std::string& name) const {
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100648 const std::vector<cricket::VideoCodec> codecs = engine_.codecs();
649 for (size_t i = 0; i < codecs.size(); ++i) {
650 const cricket::VideoCodec engine_codec = codecs[i];
Niels Möller039743e2018-10-23 10:07:25 +0200651 if (!absl::EqualsIgnoreCase(name, engine_codec.name))
Magnus Jedvert8deb8182017-10-05 13:13:32 +0200652 continue;
653 // The tests only use H264 Constrained Baseline. Make sure we don't return
654 // an internal H264 codec from the engine with a different H264 profile.
Niels Möller039743e2018-10-23 10:07:25 +0200655 if (absl::EqualsIgnoreCase(name.c_str(), kH264CodecName)) {
Danil Chapovalov00c71832018-06-15 15:58:38 +0200656 const absl::optional<webrtc::H264::ProfileLevelId> profile_level_id =
Magnus Jedvert8deb8182017-10-05 13:13:32 +0200657 webrtc::H264::ParseSdpProfileLevelId(engine_codec.params);
658 if (profile_level_id->profile !=
659 webrtc::H264::kProfileConstrainedBaseline) {
660 continue;
661 }
662 }
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100663 return i;
magjed509e4fe2016-11-18 01:34:11 -0800664 }
665 // This point should never be reached.
666 ADD_FAILURE() << "Unrecognized codec name: " << name;
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100667 return -1;
668}
669
670cricket::VideoCodec WebRtcVideoEngineTest::GetEngineCodec(
671 const std::string& name) const {
672 return engine_.codecs()[GetEngineCodecIndex(name)];
magjed509e4fe2016-11-18 01:34:11 -0800673}
674
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200675VideoMediaChannel*
676WebRtcVideoEngineTest::SetSendParamsWithAllSupportedCodecs() {
Sebastian Jansson84848f22018-11-16 10:40:36 +0100677 VideoMediaChannel* channel = engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700678 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200679 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800680 // We need to look up the codec in the engine to get the correct payload type.
Anders Carlsson67537952018-05-03 11:28:29 +0200681 for (const webrtc::SdpVideoFormat& format :
682 encoder_factory_->GetSupportedFormats()) {
683 cricket::VideoCodec engine_codec = GetEngineCodec(format.name);
684 if (std::find(parameters.codecs.begin(), parameters.codecs.end(),
685 engine_codec) == parameters.codecs.end()) {
686 parameters.codecs.push_back(engine_codec);
687 }
688 }
magjed509e4fe2016-11-18 01:34:11 -0800689
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200690 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000691
692 return channel;
693}
694
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200695VideoMediaChannel* WebRtcVideoEngineTest::SetRecvParamsWithSupportedCodecs(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000696 const std::vector<VideoCodec>& codecs) {
Sebastian Jansson84848f22018-11-16 10:40:36 +0100697 VideoMediaChannel* channel = engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700698 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200699 cricket::VideoRecvParameters parameters;
700 parameters.codecs = codecs;
701 EXPECT_TRUE(channel->SetRecvParameters(parameters));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000702
703 return channel;
704}
705
eladalonf1841382017-06-12 01:16:46 -0700706TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200707 encoder_factory_->AddSupportedVideoCodecType("VP8");
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000708
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200709 std::unique_ptr<VideoMediaChannel> channel(
710 SetSendParamsWithAllSupportedCodecs());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000711
Peter Boström0c4e06b2015-10-07 12:23:21 +0200712 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000713
Yves Gerey665174f2018-06-19 15:03:05 +0200714 EXPECT_TRUE(channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000715 EXPECT_TRUE(channel->SetSend(true));
716
Niels Möller805a27e2019-01-21 12:21:27 +0100717 webrtc::test::FrameForwarder frame_forwarder;
718 cricket::FakeFrameSource frame_source(1280, 720,
719 rtc::kNumMicrosecsPerSec / 60);
720 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, &frame_forwarder));
721 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000722
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200723 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000724
725 // Verify that encoders are configured for simulcast through adapter
726 // (increasing resolution and only configured to send one stream each).
727 int prev_width = -1;
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200728 for (size_t i = 0; i < encoder_factory_->encoders().size(); ++i) {
729 ASSERT_TRUE(encoder_factory_->encoders()[i]->WaitForInitEncode());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000730 webrtc::VideoCodec codec_settings =
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200731 encoder_factory_->encoders()[i]->GetCodecSettings();
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000732 EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
733 EXPECT_GT(codec_settings.width, prev_width);
734 prev_width = codec_settings.width;
735 }
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000736
Niels Möllerff40b142018-04-09 08:49:14 +0200737 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, nullptr));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000738
739 channel.reset();
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200740 ASSERT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000741}
742
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200743TEST_F(WebRtcVideoEngineTest, ChannelWithH264CanChangeToVp8) {
744 encoder_factory_->AddSupportedVideoCodecType("VP8");
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200745 encoder_factory_->AddSupportedVideoCodecType("H264");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000746
Niels Möllerd0f0f682019-01-14 09:09:53 +0100747 // Frame source.
748 webrtc::test::FrameForwarder frame_forwarder;
749 cricket::FakeFrameSource frame_source(1280, 720,
750 rtc::kNumMicrosecsPerSec / 30);
Niels Möller4db138e2018-04-19 09:04:13 +0200751
Sebastian Jansson84848f22018-11-16 10:40:36 +0100752 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700753 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
Anders Carlsson67537952018-05-03 11:28:29 +0200754 cricket::VideoSendParameters parameters;
755 parameters.codecs.push_back(GetEngineCodec("H264"));
756 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000757
758 EXPECT_TRUE(
759 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möllerd0f0f682019-01-14 09:09:53 +0100760 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
Niels Möller4db138e2018-04-19 09:04:13 +0200761 // Sending one frame will have allocate the encoder.
Niels Möllerd0f0f682019-01-14 09:09:53 +0100762 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +0200763
764 ASSERT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000765
Anders Carlsson67537952018-05-03 11:28:29 +0200766 cricket::VideoSendParameters new_parameters;
767 new_parameters.codecs.push_back(GetEngineCodec("VP8"));
768 EXPECT_TRUE(channel->SetSendParameters(new_parameters));
Niels Möller4db138e2018-04-19 09:04:13 +0200769
770 // Sending one frame will switch encoder.
Niels Möllerd0f0f682019-01-14 09:09:53 +0100771 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +0200772
Anders Carlsson8a150d92018-05-14 12:40:04 +0200773 EXPECT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000774}
775
eladalonf1841382017-06-12 01:16:46 -0700776TEST_F(WebRtcVideoEngineTest,
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000777 UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200778 encoder_factory_->AddSupportedVideoCodecType("VP8");
779 encoder_factory_->AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000780
Sebastian Jansson84848f22018-11-16 10:40:36 +0100781 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700782 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
magjed509e4fe2016-11-18 01:34:11 -0800783 cricket::VideoSendParameters parameters;
784 parameters.codecs.push_back(GetEngineCodec("VP8"));
785 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000786
Peter Boström0c4e06b2015-10-07 12:23:21 +0200787 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000788
Yves Gerey665174f2018-06-19 15:03:05 +0200789 EXPECT_TRUE(channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000790 EXPECT_TRUE(channel->SetSend(true));
791
792 // Send a fake frame, or else the media engine will configure the simulcast
793 // encoder adapter at a low-enough size that it'll only create a single
794 // encoder layer.
Niels Möller805a27e2019-01-21 12:21:27 +0100795 webrtc::test::FrameForwarder frame_forwarder;
796 cricket::FakeFrameSource frame_source(1280, 720,
797 rtc::kNumMicrosecsPerSec / 30);
798 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, &frame_forwarder));
799 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000800
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200801 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
802 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000803 EXPECT_EQ(webrtc::kVideoCodecVP8,
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200804 encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000805
806 channel.reset();
807 // Make sure DestroyVideoEncoder was called on the factory.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200808 EXPECT_EQ(0u, encoder_factory_->encoders().size());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000809}
810
eladalonf1841382017-06-12 01:16:46 -0700811TEST_F(WebRtcVideoEngineTest,
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000812 DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200813 encoder_factory_->AddSupportedVideoCodecType("VP8");
814 encoder_factory_->AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000815
Sebastian Jansson84848f22018-11-16 10:40:36 +0100816 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700817 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
magjed509e4fe2016-11-18 01:34:11 -0800818 cricket::VideoSendParameters parameters;
819 parameters.codecs.push_back(GetEngineCodec("H264"));
820 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000821
822 EXPECT_TRUE(
823 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Per21d45d22016-10-30 21:37:57 +0100824
825 // Send a frame of 720p. This should trigger a "real" encoder initialization.
Niels Möller805a27e2019-01-21 12:21:27 +0100826 webrtc::test::FrameForwarder frame_forwarder;
827 cricket::FakeFrameSource frame_source(1280, 720,
828 rtc::kNumMicrosecsPerSec / 30);
829 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
830 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +0200831 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
832 ASSERT_EQ(1u, encoder_factory_->encoders().size());
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200833 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000834 EXPECT_EQ(webrtc::kVideoCodecH264,
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200835 encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000836
837 channel.reset();
838 // Make sure DestroyVideoEncoder was called on the factory.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200839 ASSERT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000840}
841
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200842TEST_F(WebRtcVideoEngineTest, SimulcastEnabledForH264BehindFieldTrial) {
843 webrtc::test::ScopedFieldTrials override_field_trials_(
844 "WebRTC-H264Simulcast/Enabled/");
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200845 encoder_factory_->AddSupportedVideoCodecType("H264");
noahricfdac5162015-08-27 01:59:29 -0700846
Sebastian Jansson84848f22018-11-16 10:40:36 +0100847 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700848 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
Anders Carlsson67537952018-05-03 11:28:29 +0200849 cricket::VideoSendParameters parameters;
850 parameters.codecs.push_back(GetEngineCodec("H264"));
851 EXPECT_TRUE(channel->SetSendParameters(parameters));
noahricfdac5162015-08-27 01:59:29 -0700852
Peter Boström0c4e06b2015-10-07 12:23:21 +0200853 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
noahricfdac5162015-08-27 01:59:29 -0700854 EXPECT_TRUE(
855 channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs)));
Peter Boströmce23bee2016-02-02 14:14:30 +0100856
857 // Send a frame of 720p. This should trigger a "real" encoder initialization.
Niels Möller805a27e2019-01-21 12:21:27 +0100858 webrtc::test::FrameForwarder frame_forwarder;
859 cricket::FakeFrameSource frame_source(1280, 720,
860 rtc::kNumMicrosecsPerSec / 30);
861 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
862 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Peter Boströmce23bee2016-02-02 14:14:30 +0100863
Niels Möller4db138e2018-04-19 09:04:13 +0200864 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200865 ASSERT_EQ(1u, encoder_factory_->encoders().size());
866 FakeWebRtcVideoEncoder* encoder = encoder_factory_->encoders()[0];
867 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
noahricfdac5162015-08-27 01:59:29 -0700868 EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200869 EXPECT_LT(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
Niels Möllerff40b142018-04-09 08:49:14 +0200870 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], nullptr, nullptr));
noahricfdac5162015-08-27 01:59:29 -0700871}
872
brandtrffc61182016-11-28 06:02:22 -0800873// Test that the FlexFEC field trial properly alters the output of
eladalonf1841382017-06-12 01:16:46 -0700874// WebRtcVideoEngine::codecs(), for an existing |engine_| object.
brandtrffc61182016-11-28 06:02:22 -0800875//
876// TODO(brandtr): Remove this test, when the FlexFEC field trial is gone.
eladalonf1841382017-06-12 01:16:46 -0700877TEST_F(WebRtcVideoEngineTest,
brandtrffc61182016-11-28 06:02:22 -0800878 Flexfec03SupportedAsInternalCodecBehindFieldTrial) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200879 encoder_factory_->AddSupportedVideoCodecType("VP8");
880
brandtrffc61182016-11-28 06:02:22 -0800881 auto is_flexfec = [](const VideoCodec& codec) {
882 if (codec.name == "flexfec-03")
883 return true;
884 return false;
885 };
886
887 // FlexFEC is not active without field trial.
brandtrffc61182016-11-28 06:02:22 -0800888 const std::vector<VideoCodec> codecs_before = engine_.codecs();
889 EXPECT_EQ(codecs_before.end(), std::find_if(codecs_before.begin(),
890 codecs_before.end(), is_flexfec));
891
892 // FlexFEC is active with field trial.
893 webrtc::test::ScopedFieldTrials override_field_trials_(
brandtr340e3fd2017-02-28 15:43:10 -0800894 "WebRTC-FlexFEC-03-Advertised/Enabled/");
brandtrffc61182016-11-28 06:02:22 -0800895 const std::vector<VideoCodec> codecs_after = engine_.codecs();
896 EXPECT_NE(codecs_after.end(),
897 std::find_if(codecs_after.begin(), codecs_after.end(), is_flexfec));
898}
899
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200900// Test that codecs are added in the order they are reported from the factory.
901TEST_F(WebRtcVideoEngineTest, ReportSupportedCodecs) {
902 encoder_factory_->AddSupportedVideoCodecType("VP8");
903 const char* kFakeCodecName = "FakeCodec";
904 encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000905
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200906 // The last reported codec should appear after the first codec in the vector.
Oleh Prypina40f8242017-12-21 13:32:23 +0100907 const size_t vp8_index = GetEngineCodecIndex("VP8");
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200908 const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName);
909 EXPECT_LT(vp8_index, fake_codec_index);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000910}
911
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200912// Test that a codec that was added after the engine was initialized
brandtrffc61182016-11-28 06:02:22 -0800913// does show up in the codec list after it was added.
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200914TEST_F(WebRtcVideoEngineTest, ReportSupportedAddedCodec) {
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100915 const char* kFakeExternalCodecName1 = "FakeExternalCodec1";
916 const char* kFakeExternalCodecName2 = "FakeExternalCodec2";
Magnus Jedvert154ee1f2017-11-15 19:27:11 +0100917
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100918 // Set up external encoder factory with first codec, and initialize engine.
919 encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName1);
920
brandtrffc61182016-11-28 06:02:22 -0800921 std::vector<cricket::VideoCodec> codecs_before(engine_.codecs());
brandtrffc61182016-11-28 06:02:22 -0800922
923 // Add second codec.
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100924 encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName2);
brandtrffc61182016-11-28 06:02:22 -0800925 std::vector<cricket::VideoCodec> codecs_after(engine_.codecs());
Sami Kalliomäkie9a18b22018-07-13 10:28:21 +0200926 // The codec itself and RTX should have been added.
927 EXPECT_EQ(codecs_before.size() + 2, codecs_after.size());
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100928
929 // Check that both fake codecs are present and that the second fake codec
930 // appears after the first fake codec.
Oleh Prypina40f8242017-12-21 13:32:23 +0100931 const size_t fake_codec_index1 = GetEngineCodecIndex(kFakeExternalCodecName1);
932 const size_t fake_codec_index2 = GetEngineCodecIndex(kFakeExternalCodecName2);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100933 EXPECT_LT(fake_codec_index1, fake_codec_index2);
brandtrffc61182016-11-28 06:02:22 -0800934}
935
Sami Kalliomäkie9a18b22018-07-13 10:28:21 +0200936TEST_F(WebRtcVideoEngineTest, ReportRtxForExternalCodec) {
937 const char* kFakeCodecName = "FakeCodec";
938 encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName);
939
940 const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName);
941 EXPECT_EQ("rtx", engine_.codecs().at(fake_codec_index + 1).name);
942}
943
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200944TEST_F(WebRtcVideoEngineTest, RegisterDecodersIfSupported) {
945 encoder_factory_->AddSupportedVideoCodecType("VP8");
Anders Carlsson67537952018-05-03 11:28:29 +0200946 decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200947 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800948 parameters.codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000949
kwiberg686a8ef2016-02-26 03:00:35 -0800950 std::unique_ptr<VideoMediaChannel> channel(
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200951 SetRecvParamsWithSupportedCodecs(parameters.codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000952
953 EXPECT_TRUE(
954 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200955 ASSERT_EQ(1u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000956
957 // Setting codecs of the same type should not reallocate the decoder.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200958 EXPECT_TRUE(channel->SetRecvParameters(parameters));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200959 EXPECT_EQ(1, decoder_factory_->GetNumCreatedDecoders());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000960
961 // Remove stream previously added to free the external decoder instance.
962 EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200963 EXPECT_EQ(0u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000964}
965
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200966// Verifies that we can set up decoders.
967TEST_F(WebRtcVideoEngineTest, RegisterH264DecoderIfSupported) {
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000968 // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We
969 // can't even query the WebRtcVideoDecoderFactory for supported codecs.
970 // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
971 // codecs.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200972 encoder_factory_->AddSupportedVideoCodecType("H264");
Anders Carlsson67537952018-05-03 11:28:29 +0200973 decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("H264"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000974 std::vector<cricket::VideoCodec> codecs;
magjed509e4fe2016-11-18 01:34:11 -0800975 codecs.push_back(GetEngineCodec("H264"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000976
kwiberg686a8ef2016-02-26 03:00:35 -0800977 std::unique_ptr<VideoMediaChannel> channel(
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200978 SetRecvParamsWithSupportedCodecs(codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000979
980 EXPECT_TRUE(
981 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200982 ASSERT_EQ(1u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000983}
984
Jonas Oreland49ac5952018-09-26 16:04:32 +0200985// Tests when GetSources is called with non-existing ssrc, it will return an
986// empty list of RtpSource without crashing.
987TEST_F(WebRtcVideoEngineTest, GetSourcesWithNonExistingSsrc) {
988 // Setup an recv stream with |kSsrc|.
989 encoder_factory_->AddSupportedVideoCodecType("VP8");
990 decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("VP8"));
991 cricket::VideoRecvParameters parameters;
992 parameters.codecs.push_back(GetEngineCodec("VP8"));
993 std::unique_ptr<VideoMediaChannel> channel(
994 SetRecvParamsWithSupportedCodecs(parameters.codecs));
995
996 EXPECT_TRUE(
997 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
998
999 // Call GetSources with |kSsrc + 1| which doesn't exist.
1000 std::vector<webrtc::RtpSource> sources = channel->GetSources(kSsrc + 1);
1001 EXPECT_EQ(0u, sources.size());
1002}
1003
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001004TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullFactories) {
1005 std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory;
1006 std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory;
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001007 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory> rate_allocator_factory;
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001008 WebRtcVideoEngine engine(std::move(encoder_factory),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001009 std::move(decoder_factory),
1010 std::move(rate_allocator_factory));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001011 EXPECT_EQ(0u, engine.codecs().size());
1012}
1013
1014TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, EmptyFactories) {
1015 // |engine| take ownership of the factories.
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -07001016 webrtc::MockVideoEncoderFactory* encoder_factory =
1017 new webrtc::MockVideoEncoderFactory();
1018 webrtc::MockVideoDecoderFactory* decoder_factory =
1019 new webrtc::MockVideoDecoderFactory();
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001020 webrtc::MockVideoBitrateAllocatorFactory* rate_allocator_factory =
1021 new webrtc::MockVideoBitrateAllocatorFactory();
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001022 WebRtcVideoEngine engine(
1023 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001024 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)),
1025 (std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>(
1026 rate_allocator_factory)));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001027 EXPECT_CALL(*encoder_factory, GetSupportedFormats());
1028 EXPECT_EQ(0u, engine.codecs().size());
1029 EXPECT_CALL(*encoder_factory, Die());
1030 EXPECT_CALL(*decoder_factory, Die());
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001031 EXPECT_CALL(*rate_allocator_factory, Die());
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001032}
1033
1034// Test full behavior in the video engine when video codec factories of the new
1035// type are injected supporting the single codec Vp8. Check the returned codecs
1036// from the engine and that we will create a Vp8 encoder and decoder using the
1037// new factories.
1038TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) {
1039 // |engine| take ownership of the factories.
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -07001040 webrtc::MockVideoEncoderFactory* encoder_factory =
1041 new webrtc::MockVideoEncoderFactory();
1042 webrtc::MockVideoDecoderFactory* decoder_factory =
1043 new webrtc::MockVideoDecoderFactory();
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001044 webrtc::MockVideoBitrateAllocatorFactory* rate_allocator_factory =
1045 new webrtc::MockVideoBitrateAllocatorFactory();
1046 EXPECT_CALL(*rate_allocator_factory,
1047 CreateVideoBitrateAllocatorProxy(Field(
1048 &webrtc::VideoCodec::codecType, webrtc::kVideoCodecVP8)))
1049 .WillOnce(testing::Return(new webrtc::MockVideoBitrateAllocator()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001050 WebRtcVideoEngine engine(
1051 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001052 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)),
1053 (std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>(
1054 rate_allocator_factory)));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001055 const webrtc::SdpVideoFormat vp8_format("VP8");
1056 const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
1057 EXPECT_CALL(*encoder_factory, GetSupportedFormats())
1058 .WillRepeatedly(testing::Return(supported_formats));
1059
1060 // Verify the codecs from the engine.
1061 const std::vector<VideoCodec> engine_codecs = engine.codecs();
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001062 // Verify default codecs has been added correctly.
1063 EXPECT_EQ(5u, engine_codecs.size());
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001064 EXPECT_EQ("VP8", engine_codecs.at(0).name);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001065
1066 // RTX codec for VP8.
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001067 EXPECT_EQ("rtx", engine_codecs.at(1).name);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001068 int vp8_associated_payload;
1069 EXPECT_TRUE(engine_codecs.at(1).GetParam(kCodecParamAssociatedPayloadType,
1070 &vp8_associated_payload));
1071 EXPECT_EQ(vp8_associated_payload, engine_codecs.at(0).id);
1072
1073 EXPECT_EQ(kRedCodecName, engine_codecs.at(2).name);
1074
1075 // RTX codec for RED.
1076 EXPECT_EQ("rtx", engine_codecs.at(3).name);
1077 int red_associated_payload;
1078 EXPECT_TRUE(engine_codecs.at(3).GetParam(kCodecParamAssociatedPayloadType,
1079 &red_associated_payload));
1080 EXPECT_EQ(red_associated_payload, engine_codecs.at(2).id);
1081
1082 EXPECT_EQ(kUlpfecCodecName, engine_codecs.at(4).name);
1083
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001084 int associated_payload_type;
1085 EXPECT_TRUE(engine_codecs.at(1).GetParam(
1086 cricket::kCodecParamAssociatedPayloadType, &associated_payload_type));
1087 EXPECT_EQ(engine_codecs.at(0).id, associated_payload_type);
1088 // Verify default parameters has been added to the VP8 codec.
1089 VerifyCodecHasDefaultFeedbackParams(engine_codecs.at(0));
1090
1091 // Mock encoder creation. |engine| take ownership of the encoder.
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00001092 webrtc::VideoEncoderFactory::CodecInfo codec_info;
1093 codec_info.is_hardware_accelerated = false;
1094 codec_info.has_internal_source = false;
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001095 const webrtc::SdpVideoFormat format("VP8");
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00001096 EXPECT_CALL(*encoder_factory, QueryVideoEncoder(format))
1097 .WillRepeatedly(testing::Return(codec_info));
Anders Carlsson67537952018-05-03 11:28:29 +02001098 FakeWebRtcVideoEncoder* const encoder = new FakeWebRtcVideoEncoder(nullptr);
Niels Möllerc572ff32018-11-07 08:43:50 +01001099 rtc::Event encoder_created;
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001100 EXPECT_CALL(*encoder_factory, CreateVideoEncoderProxy(format))
Niels Möller4db138e2018-04-19 09:04:13 +02001101 .WillOnce(
1102 ::testing::DoAll(::testing::InvokeWithoutArgs(
1103 [&encoder_created]() { encoder_created.Set(); }),
1104 ::testing::Return(encoder)));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001105
1106 // Mock decoder creation. |engine| take ownership of the decoder.
Anders Carlsson67537952018-05-03 11:28:29 +02001107 FakeWebRtcVideoDecoder* const decoder = new FakeWebRtcVideoDecoder(nullptr);
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001108 EXPECT_CALL(*decoder_factory, CreateVideoDecoderProxy(format))
1109 .WillOnce(testing::Return(decoder));
1110
1111 // Create a call.
1112 webrtc::RtcEventLogNullImpl event_log;
1113 std::unique_ptr<webrtc::Call> call(
1114 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
1115
1116 // Create send channel.
1117 const int send_ssrc = 123;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001118 std::unique_ptr<VideoMediaChannel> send_channel(engine.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07001119 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001120 cricket::VideoSendParameters send_parameters;
1121 send_parameters.codecs.push_back(engine_codecs.at(0));
1122 EXPECT_TRUE(send_channel->SetSendParameters(send_parameters));
1123 send_channel->OnReadyToSend(true);
1124 EXPECT_TRUE(
1125 send_channel->AddSendStream(StreamParams::CreateLegacy(send_ssrc)));
1126 EXPECT_TRUE(send_channel->SetSend(true));
1127
Niels Möller4db138e2018-04-19 09:04:13 +02001128 // Set capturer.
Niels Möller805a27e2019-01-21 12:21:27 +01001129 webrtc::test::FrameForwarder frame_forwarder;
1130 cricket::FakeFrameSource frame_source(1280, 720,
1131 rtc::kNumMicrosecsPerSec / 30);
1132 EXPECT_TRUE(send_channel->SetVideoSend(send_ssrc, nullptr, &frame_forwarder));
Niels Möller4db138e2018-04-19 09:04:13 +02001133 // Sending one frame will allocate the encoder.
Niels Möller805a27e2019-01-21 12:21:27 +01001134 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +02001135 encoder_created.Wait(kTimeout);
1136
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001137 // Create recv channel.
1138 const int recv_ssrc = 321;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001139 std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07001140 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001141 cricket::VideoRecvParameters recv_parameters;
1142 recv_parameters.codecs.push_back(engine_codecs.at(0));
1143 EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
1144 EXPECT_TRUE(recv_channel->AddRecvStream(
1145 cricket::StreamParams::CreateLegacy(recv_ssrc)));
1146
1147 // Remove streams previously added to free the encoder and decoder instance.
1148 EXPECT_CALL(*encoder_factory, Die());
1149 EXPECT_CALL(*decoder_factory, Die());
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001150 EXPECT_CALL(*rate_allocator_factory, Die());
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001151 EXPECT_TRUE(send_channel->RemoveSendStream(send_ssrc));
1152 EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
1153}
1154
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001155// Test behavior when decoder factory fails to create a decoder (returns null).
1156TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullDecoder) {
1157 // |engine| take ownership of the factories.
1158 webrtc::MockVideoEncoderFactory* encoder_factory =
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001159 new webrtc::MockVideoEncoderFactory();
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001160 webrtc::MockVideoDecoderFactory* decoder_factory =
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001161 new webrtc::MockVideoDecoderFactory();
1162 webrtc::MockVideoBitrateAllocatorFactory* rate_allocator_factory =
1163 new webrtc::MockVideoBitrateAllocatorFactory();
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001164 WebRtcVideoEngine engine(
1165 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001166 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)),
1167 (std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>(
1168 rate_allocator_factory)));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001169 const webrtc::SdpVideoFormat vp8_format("VP8");
1170 const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
1171 EXPECT_CALL(*encoder_factory, GetSupportedFormats())
1172 .WillRepeatedly(testing::Return(supported_formats));
1173
1174 // Decoder creation fails.
1175 EXPECT_CALL(*decoder_factory, CreateVideoDecoderProxy(testing::_))
1176 .WillOnce(testing::Return(nullptr));
1177
1178 // Create a call.
1179 webrtc::RtcEventLogNullImpl event_log;
1180 std::unique_ptr<webrtc::Call> call(
1181 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
1182
1183 // Create recv channel.
1184 const int recv_ssrc = 321;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001185 std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07001186 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001187 cricket::VideoRecvParameters recv_parameters;
1188 recv_parameters.codecs.push_back(engine.codecs().front());
1189 EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
1190 EXPECT_TRUE(recv_channel->AddRecvStream(
1191 cricket::StreamParams::CreateLegacy(recv_ssrc)));
1192
1193 // Remove streams previously added to free the encoder and decoder instance.
1194 EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
1195}
1196
eladalonf1841382017-06-12 01:16:46 -07001197TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001198 encoder_factory_->AddSupportedVideoCodecType("VP8");
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001199 std::unique_ptr<FakeCall> fake_call(new FakeCall());
Anders Carlsson5f2bb622018-05-14 09:48:06 +02001200 std::unique_ptr<VideoMediaChannel> channel(
1201 SetSendParamsWithAllSupportedCodecs());
sprangf24a0642017-02-28 13:23:26 -08001202 ASSERT_TRUE(
1203 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1204 cricket::VideoCodec codec = GetEngineCodec("VP8");
1205 cricket::VideoSendParameters parameters;
1206 parameters.codecs.push_back(codec);
1207 channel->OnReadyToSend(true);
1208 channel->SetSend(true);
1209 ASSERT_TRUE(channel->SetSendParameters(parameters));
1210
Niels Möller805a27e2019-01-21 12:21:27 +01001211 webrtc::test::FrameForwarder frame_forwarder;
1212 cricket::FakeFrameSource frame_source(1280, 720,
1213 rtc::kNumMicrosecsPerSec / 30);
sprangf24a0642017-02-28 13:23:26 -08001214 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01001215 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08001216
Niels Möller805a27e2019-01-21 12:21:27 +01001217 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001218 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001219 EXPECT_EQ(webrtc::VideoCodecMode::kRealtimeVideo,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001220 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001221
Niels Möller805a27e2019-01-21 12:21:27 +01001222 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1223 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08001224 // No change in content type, keep current encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001225 EXPECT_EQ(1, encoder_factory_->GetNumCreatedEncoders());
sprangf24a0642017-02-28 13:23:26 -08001226
1227 options.is_screencast.emplace(true);
Niels Möller805a27e2019-01-21 12:21:27 +01001228 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1229 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08001230 // Change to screen content, recreate encoder. For the simulcast encoder
1231 // adapter case, this will result in two calls since InitEncode triggers a
1232 // a new instance.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001233 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001234 EXPECT_EQ(webrtc::VideoCodecMode::kScreensharing,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001235 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001236
Niels Möller805a27e2019-01-21 12:21:27 +01001237 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1238 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08001239 // Still screen content, no need to update encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001240 EXPECT_EQ(2, encoder_factory_->GetNumCreatedEncoders());
sprangf24a0642017-02-28 13:23:26 -08001241
1242 options.is_screencast.emplace(false);
1243 options.video_noise_reduction.emplace(false);
Niels Möller805a27e2019-01-21 12:21:27 +01001244 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08001245 // Change back to regular video content, update encoder. Also change
1246 // a non |is_screencast| option just to verify it doesn't affect recreation.
Niels Möller805a27e2019-01-21 12:21:27 +01001247 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001248 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(3));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001249 EXPECT_EQ(webrtc::VideoCodecMode::kRealtimeVideo,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001250 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001251
1252 // Remove stream previously added to free the external encoder instance.
1253 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001254 EXPECT_EQ(0u, encoder_factory_->encoders().size());
sprangf24a0642017-02-28 13:23:26 -08001255}
1256
Niels Möller6557d0c2018-04-11 15:18:34 +02001257class WebRtcVideoChannelBaseTest : public testing::Test {
1258 protected:
1259 WebRtcVideoChannelBaseTest()
Jonas Oreland49ac5952018-09-26 16:04:32 +02001260 : engine_(webrtc::CreateBuiltinVideoEncoderFactory(),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001261 webrtc::CreateBuiltinVideoDecoderFactory(),
1262 webrtc::CreateBuiltinVideoBitrateAllocatorFactory()) {}
Niels Möller6557d0c2018-04-11 15:18:34 +02001263
1264 virtual void SetUp() {
Jonas Oreland49ac5952018-09-26 16:04:32 +02001265 // One testcase calls SetUp in a loop, only create call_ once.
1266 if (!call_) {
1267 call_.reset(webrtc::Call::Create(webrtc::Call::Config(&event_log_)));
1268 }
Niels Möller6557d0c2018-04-11 15:18:34 +02001269 cricket::MediaConfig media_config;
1270 // Disabling cpu overuse detection actually disables quality scaling too; it
1271 // implies DegradationPreference kMaintainResolution. Automatic scaling
1272 // needs to be disabled, otherwise, tests which check the size of received
1273 // frames become flaky.
1274 media_config.video.enable_cpu_adaptation = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001275 channel_.reset(
1276 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
1277 call_.get(), media_config, cricket::VideoOptions(),
1278 webrtc::CryptoOptions())));
Niels Möller6557d0c2018-04-11 15:18:34 +02001279 channel_->OnReadyToSend(true);
1280 EXPECT_TRUE(channel_.get() != NULL);
1281 network_interface_.SetDestination(channel_.get());
Anton Sukhanov98a462c2018-10-17 13:15:42 -07001282 channel_->SetInterface(&network_interface_, /*media_transport=*/nullptr);
Niels Möller6557d0c2018-04-11 15:18:34 +02001283 cricket::VideoRecvParameters parameters;
1284 parameters.codecs = engine_.codecs();
1285 channel_->SetRecvParameters(parameters);
1286 EXPECT_TRUE(channel_->AddSendStream(DefaultSendStreamParams()));
Niels Möller805a27e2019-01-21 12:21:27 +01001287 frame_forwarder_ = absl::make_unique<webrtc::test::FrameForwarder>();
1288 frame_source_ = absl::make_unique<cricket::FakeFrameSource>(
1289 640, 480, rtc::kNumMicrosecsPerSec / kFramerate);
1290 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001291 }
1292
1293 // Utility method to setup an additional stream to send and receive video.
1294 // Used to test send and recv between two streams.
1295 void SetUpSecondStream() {
1296 SetUpSecondStreamWithNoRecv();
1297 // Setup recv for second stream.
1298 EXPECT_TRUE(channel_->AddRecvStream(
1299 cricket::StreamParams::CreateLegacy(kSsrc + 2)));
1300 // Make the second renderer available for use by a new stream.
1301 EXPECT_TRUE(channel_->SetSink(kSsrc + 2, &renderer2_));
1302 }
1303 // Setup an additional stream just to send video. Defer add recv stream.
1304 // This is required if you want to test unsignalled recv of video rtp packets.
1305 void SetUpSecondStreamWithNoRecv() {
1306 // SetUp() already added kSsrc make sure duplicate SSRCs cant be added.
Yves Gerey665174f2018-06-19 15:03:05 +02001307 EXPECT_TRUE(
1308 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001309 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
Yves Gerey665174f2018-06-19 15:03:05 +02001310 EXPECT_FALSE(
1311 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001312 EXPECT_TRUE(channel_->AddSendStream(
1313 cricket::StreamParams::CreateLegacy(kSsrc + 2)));
1314 // We dont add recv for the second stream.
1315
1316 // Setup the receive and renderer for second stream after send.
Niels Möller805a27e2019-01-21 12:21:27 +01001317 frame_forwarder_2_ = absl::make_unique<webrtc::test::FrameForwarder>();
Yves Gerey665174f2018-06-19 15:03:05 +02001318 EXPECT_TRUE(
Niels Möller805a27e2019-01-21 12:21:27 +01001319 channel_->SetVideoSend(kSsrc + 2, nullptr, frame_forwarder_2_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001320 }
Yves Gerey665174f2018-06-19 15:03:05 +02001321 virtual void TearDown() { channel_.reset(); }
1322 bool SetDefaultCodec() { return SetOneCodec(DefaultCodec()); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001323
1324 bool SetOneCodec(const cricket::VideoCodec& codec) {
Niels Möller805a27e2019-01-21 12:21:27 +01001325 frame_source_ = absl::make_unique<cricket::FakeFrameSource>(
1326 kVideoWidth, kVideoHeight, rtc::kNumMicrosecsPerSec / kFramerate);
Niels Möller6557d0c2018-04-11 15:18:34 +02001327
1328 bool sending = channel_->sending();
1329 bool success = SetSend(false);
1330 if (success) {
1331 cricket::VideoSendParameters parameters;
1332 parameters.codecs.push_back(codec);
1333 success = channel_->SetSendParameters(parameters);
1334 }
1335 if (success) {
1336 success = SetSend(sending);
1337 }
1338 return success;
1339 }
Yves Gerey665174f2018-06-19 15:03:05 +02001340 bool SetSend(bool send) { return channel_->SetSend(send); }
Niels Möller805a27e2019-01-21 12:21:27 +01001341 void SendFrame() {
1342 if (frame_forwarder_2_) {
1343 frame_forwarder_2_->IncomingCapturedFrame(frame_source_->GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02001344 }
Niels Möller805a27e2019-01-21 12:21:27 +01001345 frame_forwarder_->IncomingCapturedFrame(frame_source_->GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02001346 }
1347 bool WaitAndSendFrame(int wait_ms) {
1348 bool ret = rtc::Thread::Current()->ProcessMessages(wait_ms);
Niels Möller805a27e2019-01-21 12:21:27 +01001349 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001350 return ret;
1351 }
Yves Gerey665174f2018-06-19 15:03:05 +02001352 int NumRtpBytes() { return network_interface_.NumRtpBytes(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001353 int NumRtpBytes(uint32_t ssrc) {
1354 return network_interface_.NumRtpBytes(ssrc);
1355 }
Yves Gerey665174f2018-06-19 15:03:05 +02001356 int NumRtpPackets() { return network_interface_.NumRtpPackets(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001357 int NumRtpPackets(uint32_t ssrc) {
1358 return network_interface_.NumRtpPackets(ssrc);
1359 }
Yves Gerey665174f2018-06-19 15:03:05 +02001360 int NumSentSsrcs() { return network_interface_.NumSentSsrcs(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001361 const rtc::CopyOnWriteBuffer* GetRtpPacket(int index) {
1362 return network_interface_.GetRtpPacket(index);
1363 }
1364 static int GetPayloadType(const rtc::CopyOnWriteBuffer* p) {
Åsa Persson23cd45a2018-07-03 10:40:40 +02001365 webrtc::RTPHeader header;
1366 EXPECT_TRUE(ParseRtpPacket(p, &header));
1367 return header.payloadType;
Niels Möller6557d0c2018-04-11 15:18:34 +02001368 }
Åsa Persson23cd45a2018-07-03 10:40:40 +02001369
Niels Möller6557d0c2018-04-11 15:18:34 +02001370 static bool ParseRtpPacket(const rtc::CopyOnWriteBuffer* p,
Åsa Persson23cd45a2018-07-03 10:40:40 +02001371 webrtc::RTPHeader* header) {
1372 std::unique_ptr<webrtc::RtpHeaderParser> parser(
1373 webrtc::RtpHeaderParser::Create());
1374 return parser->Parse(p->cdata(), p->size(), header);
Niels Möller6557d0c2018-04-11 15:18:34 +02001375 }
1376
1377 // Tests that we can send and receive frames.
1378 void SendAndReceive(const cricket::VideoCodec& codec) {
1379 EXPECT_TRUE(SetOneCodec(codec));
1380 EXPECT_TRUE(SetSend(true));
1381 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1382 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01001383 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001384 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1385 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1386 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
1387 }
1388
1389 void SendReceiveManyAndGetStats(const cricket::VideoCodec& codec,
Yves Gerey665174f2018-06-19 15:03:05 +02001390 int duration_sec,
1391 int fps) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001392 EXPECT_TRUE(SetOneCodec(codec));
1393 EXPECT_TRUE(SetSend(true));
1394 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1395 EXPECT_EQ(0, renderer_.num_rendered_frames());
1396 for (int i = 0; i < duration_sec; ++i) {
1397 for (int frame = 1; frame <= fps; ++frame) {
1398 EXPECT_TRUE(WaitAndSendFrame(1000 / fps));
1399 EXPECT_FRAME_WAIT(frame + i * fps, kVideoWidth, kVideoHeight, kTimeout);
1400 }
1401 }
1402 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1403 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
1404 }
1405
Niels Möller6557d0c2018-04-11 15:18:34 +02001406 cricket::VideoSenderInfo GetSenderStats(size_t i) {
1407 cricket::VideoMediaInfo info;
1408 EXPECT_TRUE(channel_->GetStats(&info));
1409 return info.senders[i];
1410 }
1411
1412 cricket::VideoReceiverInfo GetReceiverStats(size_t i) {
1413 cricket::VideoMediaInfo info;
1414 EXPECT_TRUE(channel_->GetStats(&info));
1415 return info.receivers[i];
1416 }
1417
1418 // Two streams one channel tests.
1419
1420 // Tests that we can send and receive frames.
1421 void TwoStreamsSendAndReceive(const cricket::VideoCodec& codec) {
1422 SetUpSecondStream();
1423 // Test sending and receiving on first stream.
1424 SendAndReceive(codec);
1425 // Test sending and receiving on second stream.
1426 EXPECT_EQ_WAIT(1, renderer2_.num_rendered_frames(), kTimeout);
1427 EXPECT_GT(NumRtpPackets(), 0);
1428 EXPECT_EQ(1, renderer2_.num_rendered_frames());
1429 }
1430
1431 cricket::VideoCodec GetEngineCodec(const std::string& name) {
1432 for (const cricket::VideoCodec& engine_codec : engine_.codecs()) {
Niels Möller039743e2018-10-23 10:07:25 +02001433 if (absl::EqualsIgnoreCase(name, engine_codec.name))
Niels Möller6557d0c2018-04-11 15:18:34 +02001434 return engine_codec;
1435 }
1436 // This point should never be reached.
1437 ADD_FAILURE() << "Unrecognized codec name: " << name;
1438 return cricket::VideoCodec();
1439 }
1440
1441 cricket::VideoCodec DefaultCodec() { return GetEngineCodec("VP8"); }
1442
1443 cricket::StreamParams DefaultSendStreamParams() {
1444 return cricket::StreamParams::CreateLegacy(kSsrc);
1445 }
1446
1447 webrtc::RtcEventLogNullImpl event_log_;
Jonas Oreland49ac5952018-09-26 16:04:32 +02001448 std::unique_ptr<webrtc::Call> call_;
Niels Möller6557d0c2018-04-11 15:18:34 +02001449 WebRtcVideoEngine engine_;
Niels Möller805a27e2019-01-21 12:21:27 +01001450
1451 std::unique_ptr<cricket::FakeFrameSource> frame_source_;
1452 std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_;
1453 std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_2_;
1454
Niels Möller6557d0c2018-04-11 15:18:34 +02001455 std::unique_ptr<WebRtcVideoChannel> channel_;
1456 cricket::FakeNetworkInterface network_interface_;
1457 cricket::FakeVideoRenderer renderer_;
1458
1459 // Used by test cases where 2 streams are run on the same channel.
1460 cricket::FakeVideoRenderer renderer2_;
1461};
1462
1463// Test that SetSend works.
srtee0c2eea2017-12-15 17:44:33 +01001464TEST_F(WebRtcVideoChannelBaseTest, SetSend) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001465 EXPECT_FALSE(channel_->sending());
Niels Möller805a27e2019-01-21 12:21:27 +01001466 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001467 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1468 EXPECT_FALSE(channel_->sending());
1469 EXPECT_TRUE(SetSend(true));
1470 EXPECT_TRUE(channel_->sending());
Niels Möller805a27e2019-01-21 12:21:27 +01001471 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001472 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
1473 EXPECT_TRUE(SetSend(false));
1474 EXPECT_FALSE(channel_->sending());
srtee0c2eea2017-12-15 17:44:33 +01001475}
Niels Möller6557d0c2018-04-11 15:18:34 +02001476
1477// Test that SetSend fails without codecs being set.
srtee0c2eea2017-12-15 17:44:33 +01001478TEST_F(WebRtcVideoChannelBaseTest, SetSendWithoutCodecs) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001479 EXPECT_FALSE(channel_->sending());
1480 EXPECT_FALSE(SetSend(true));
1481 EXPECT_FALSE(channel_->sending());
srtee0c2eea2017-12-15 17:44:33 +01001482}
Niels Möller6557d0c2018-04-11 15:18:34 +02001483
1484// Test that we properly set the send and recv buffer sizes by the time
1485// SetSend is called.
srtee0c2eea2017-12-15 17:44:33 +01001486TEST_F(WebRtcVideoChannelBaseTest, SetSendSetsTransportBufferSizes) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001487 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1488 EXPECT_TRUE(SetSend(true));
1489 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
Johannes Krond38a2b82018-10-23 11:31:19 +02001490 EXPECT_EQ(256 * 1024, network_interface_.recvbuf_size());
Erik Språng820ebd02018-08-20 17:14:25 +02001491}
1492
Niels Möller6557d0c2018-04-11 15:18:34 +02001493// Test that stats work properly for a 1-1 call.
srtee0c2eea2017-12-15 17:44:33 +01001494TEST_F(WebRtcVideoChannelBaseTest, GetStats) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001495 const int kDurationSec = 3;
1496 const int kFps = 10;
1497 SendReceiveManyAndGetStats(DefaultCodec(), kDurationSec, kFps);
1498
1499 cricket::VideoMediaInfo info;
1500 EXPECT_TRUE(channel_->GetStats(&info));
1501
1502 ASSERT_EQ(1U, info.senders.size());
1503 // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
1504 // For webrtc, bytes_sent does not include the RTP header length.
1505 EXPECT_GT(info.senders[0].bytes_sent, 0);
1506 EXPECT_EQ(NumRtpPackets(), info.senders[0].packets_sent);
1507 EXPECT_EQ(0.0, info.senders[0].fraction_lost);
1508 ASSERT_TRUE(info.senders[0].codec_payload_type);
1509 EXPECT_EQ(DefaultCodec().id, *info.senders[0].codec_payload_type);
1510 EXPECT_EQ(0, info.senders[0].firs_rcvd);
1511 EXPECT_EQ(0, info.senders[0].plis_rcvd);
1512 EXPECT_EQ(0, info.senders[0].nacks_rcvd);
1513 EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width);
1514 EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height);
1515 EXPECT_GT(info.senders[0].framerate_input, 0);
1516 EXPECT_GT(info.senders[0].framerate_sent, 0);
1517
1518 EXPECT_EQ(1U, info.send_codecs.count(DefaultCodec().id));
1519 EXPECT_EQ(DefaultCodec().ToCodecParameters(),
1520 info.send_codecs[DefaultCodec().id]);
1521
1522 ASSERT_EQ(1U, info.receivers.size());
1523 EXPECT_EQ(1U, info.senders[0].ssrcs().size());
1524 EXPECT_EQ(1U, info.receivers[0].ssrcs().size());
1525 EXPECT_EQ(info.senders[0].ssrcs()[0], info.receivers[0].ssrcs()[0]);
1526 ASSERT_TRUE(info.receivers[0].codec_payload_type);
1527 EXPECT_EQ(DefaultCodec().id, *info.receivers[0].codec_payload_type);
1528 EXPECT_EQ(NumRtpBytes(), info.receivers[0].bytes_rcvd);
1529 EXPECT_EQ(NumRtpPackets(), info.receivers[0].packets_rcvd);
1530 EXPECT_EQ(0.0, info.receivers[0].fraction_lost);
1531 EXPECT_EQ(0, info.receivers[0].packets_lost);
1532 // TODO(asapersson): Not set for webrtc. Handle missing stats.
1533 // EXPECT_EQ(0, info.receivers[0].packets_concealed);
1534 EXPECT_EQ(0, info.receivers[0].firs_sent);
1535 EXPECT_EQ(0, info.receivers[0].plis_sent);
1536 EXPECT_EQ(0, info.receivers[0].nacks_sent);
1537 EXPECT_EQ(kVideoWidth, info.receivers[0].frame_width);
1538 EXPECT_EQ(kVideoHeight, info.receivers[0].frame_height);
1539 EXPECT_GT(info.receivers[0].framerate_rcvd, 0);
1540 EXPECT_GT(info.receivers[0].framerate_decoded, 0);
1541 EXPECT_GT(info.receivers[0].framerate_output, 0);
1542
1543 EXPECT_EQ(1U, info.receive_codecs.count(DefaultCodec().id));
1544 EXPECT_EQ(DefaultCodec().ToCodecParameters(),
1545 info.receive_codecs[DefaultCodec().id]);
srtee0c2eea2017-12-15 17:44:33 +01001546}
Niels Möller6557d0c2018-04-11 15:18:34 +02001547
1548// Test that stats work properly for a conf call with multiple recv streams.
srtee0c2eea2017-12-15 17:44:33 +01001549TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleRecvStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001550 cricket::FakeVideoRenderer renderer1, renderer2;
1551 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1552 cricket::VideoSendParameters parameters;
1553 parameters.codecs.push_back(DefaultCodec());
1554 parameters.conference_mode = true;
1555 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1556 EXPECT_TRUE(SetSend(true));
Yves Gerey665174f2018-06-19 15:03:05 +02001557 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1558 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001559 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
1560 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
1561 EXPECT_EQ(0, renderer1.num_rendered_frames());
1562 EXPECT_EQ(0, renderer2.num_rendered_frames());
1563 std::vector<uint32_t> ssrcs;
1564 ssrcs.push_back(1);
1565 ssrcs.push_back(2);
1566 network_interface_.SetConferenceMode(true, ssrcs);
Niels Möller805a27e2019-01-21 12:21:27 +01001567 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001568 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight,
1569 kTimeout);
1570 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight,
1571 kTimeout);
1572
1573 EXPECT_TRUE(channel_->SetSend(false));
1574
1575 cricket::VideoMediaInfo info;
1576 EXPECT_TRUE(channel_->GetStats(&info));
1577 ASSERT_EQ(1U, info.senders.size());
1578 // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
1579 // For webrtc, bytes_sent does not include the RTP header length.
1580 EXPECT_GT(GetSenderStats(0).bytes_sent, 0);
1581 EXPECT_EQ_WAIT(NumRtpPackets(), GetSenderStats(0).packets_sent, kTimeout);
1582 EXPECT_EQ(kVideoWidth, GetSenderStats(0).send_frame_width);
1583 EXPECT_EQ(kVideoHeight, GetSenderStats(0).send_frame_height);
1584
1585 ASSERT_EQ(2U, info.receivers.size());
1586 for (size_t i = 0; i < info.receivers.size(); ++i) {
1587 EXPECT_EQ(1U, GetReceiverStats(i).ssrcs().size());
1588 EXPECT_EQ(i + 1, GetReceiverStats(i).ssrcs()[0]);
1589 EXPECT_EQ_WAIT(NumRtpBytes(), GetReceiverStats(i).bytes_rcvd, kTimeout);
Yves Gerey665174f2018-06-19 15:03:05 +02001590 EXPECT_EQ_WAIT(NumRtpPackets(), GetReceiverStats(i).packets_rcvd, kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001591 EXPECT_EQ_WAIT(kVideoWidth, GetReceiverStats(i).frame_width, kTimeout);
1592 EXPECT_EQ_WAIT(kVideoHeight, GetReceiverStats(i).frame_height, kTimeout);
1593 }
srtee0c2eea2017-12-15 17:44:33 +01001594}
Niels Möller6557d0c2018-04-11 15:18:34 +02001595
1596// Test that stats work properly for a conf call with multiple send streams.
srtee0c2eea2017-12-15 17:44:33 +01001597TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001598 // Normal setup; note that we set the SSRC explicitly to ensure that
1599 // it will come first in the senders map.
1600 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1601 cricket::VideoSendParameters parameters;
1602 parameters.codecs.push_back(DefaultCodec());
1603 parameters.conference_mode = true;
1604 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Yves Gerey665174f2018-06-19 15:03:05 +02001605 EXPECT_TRUE(
1606 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001607 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1608 EXPECT_TRUE(SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01001609 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001610 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
1611 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1612
1613 // Add an additional capturer, and hook up a renderer to receive it.
1614 cricket::FakeVideoRenderer renderer2;
Niels Möller805a27e2019-01-21 12:21:27 +01001615 webrtc::test::FrameForwarder frame_forwarder;
Niels Möller6557d0c2018-04-11 15:18:34 +02001616 const int kTestWidth = 160;
1617 const int kTestHeight = 120;
Niels Möller805a27e2019-01-21 12:21:27 +01001618 cricket::FakeFrameSource frame_source(kTestWidth, kTestHeight,
1619 rtc::kNumMicrosecsPerSec / 5);
Yves Gerey665174f2018-06-19 15:03:05 +02001620 EXPECT_TRUE(
1621 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(5678)));
Niels Möller805a27e2019-01-21 12:21:27 +01001622 EXPECT_TRUE(channel_->SetVideoSend(5678, nullptr, &frame_forwarder));
Yves Gerey665174f2018-06-19 15:03:05 +02001623 EXPECT_TRUE(
1624 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(5678)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001625 EXPECT_TRUE(channel_->SetSink(5678, &renderer2));
Niels Möller805a27e2019-01-21 12:21:27 +01001626 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Yves Gerey665174f2018-06-19 15:03:05 +02001627 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight,
1628 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001629
1630 // Get stats, and make sure they are correct for two senders. We wait until
1631 // the number of expected packets have been sent to avoid races where we
1632 // check stats before it has been updated.
1633 cricket::VideoMediaInfo info;
1634 for (uint32_t i = 0; i < kTimeout; ++i) {
1635 rtc::Thread::Current()->ProcessMessages(1);
1636 EXPECT_TRUE(channel_->GetStats(&info));
1637 ASSERT_EQ(2U, info.senders.size());
1638 if (info.senders[0].packets_sent + info.senders[1].packets_sent ==
1639 NumRtpPackets()) {
1640 // Stats have been updated for both sent frames, expectations can be
1641 // checked now.
1642 break;
1643 }
1644 }
1645 EXPECT_EQ(NumRtpPackets(),
1646 info.senders[0].packets_sent + info.senders[1].packets_sent)
1647 << "Timed out while waiting for packet counts for all sent packets.";
1648 EXPECT_EQ(1U, info.senders[0].ssrcs().size());
1649 EXPECT_EQ(1234U, info.senders[0].ssrcs()[0]);
1650 EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width);
1651 EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height);
1652 EXPECT_EQ(1U, info.senders[1].ssrcs().size());
1653 EXPECT_EQ(5678U, info.senders[1].ssrcs()[0]);
1654 EXPECT_EQ(kTestWidth, info.senders[1].send_frame_width);
1655 EXPECT_EQ(kTestHeight, info.senders[1].send_frame_height);
1656 // The capturer must be unregistered here as it runs out of it's scope next.
1657 channel_->SetVideoSend(5678, nullptr, nullptr);
srtee0c2eea2017-12-15 17:44:33 +01001658}
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001659
Niels Möller6557d0c2018-04-11 15:18:34 +02001660// Test that we can set the bandwidth.
srtee0c2eea2017-12-15 17:44:33 +01001661TEST_F(WebRtcVideoChannelBaseTest, SetSendBandwidth) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001662 cricket::VideoSendParameters parameters;
1663 parameters.codecs.push_back(DefaultCodec());
1664 parameters.max_bandwidth_bps = -1; // <= 0 means unlimited.
1665 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1666 parameters.max_bandwidth_bps = 128 * 1024;
1667 EXPECT_TRUE(channel_->SetSendParameters(parameters));
srtee0c2eea2017-12-15 17:44:33 +01001668}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001669
Niels Möller6557d0c2018-04-11 15:18:34 +02001670// Test that we can set the SSRC for the default send source.
srtee0c2eea2017-12-15 17:44:33 +01001671TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrc) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001672 EXPECT_TRUE(SetDefaultCodec());
1673 EXPECT_TRUE(SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01001674 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001675 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
Åsa Persson23cd45a2018-07-03 10:40:40 +02001676 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02001677 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001678 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1679 EXPECT_EQ(kSsrc, header.ssrc);
1680
Niels Möller6557d0c2018-04-11 15:18:34 +02001681 // Packets are being paced out, so these can mismatch between the first and
1682 // second call to NumRtpPackets until pending packets are paced out.
Åsa Persson23cd45a2018-07-03 10:40:40 +02001683 EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.ssrc), kTimeout);
1684 EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.ssrc), kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001685 EXPECT_EQ(1, NumSentSsrcs());
1686 EXPECT_EQ(0, NumRtpPackets(kSsrc - 1));
1687 EXPECT_EQ(0, NumRtpBytes(kSsrc - 1));
srtee0c2eea2017-12-15 17:44:33 +01001688}
Niels Möller6557d0c2018-04-11 15:18:34 +02001689
1690// Test that we can set the SSRC even after codecs are set.
srtee0c2eea2017-12-15 17:44:33 +01001691TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrcAfterSetCodecs) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001692 // Remove stream added in Setup.
1693 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1694 EXPECT_TRUE(SetDefaultCodec());
Niels Möller6557d0c2018-04-11 15:18:34 +02001695 EXPECT_TRUE(
Yves Gerey665174f2018-06-19 15:03:05 +02001696 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(999)));
Niels Möller805a27e2019-01-21 12:21:27 +01001697 EXPECT_TRUE(channel_->SetVideoSend(999u, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001698 EXPECT_TRUE(SetSend(true));
1699 EXPECT_TRUE(WaitAndSendFrame(0));
1700 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
Åsa Persson23cd45a2018-07-03 10:40:40 +02001701 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02001702 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001703 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1704 EXPECT_EQ(999u, header.ssrc);
Niels Möller6557d0c2018-04-11 15:18:34 +02001705 // Packets are being paced out, so these can mismatch between the first and
1706 // second call to NumRtpPackets until pending packets are paced out.
Åsa Persson23cd45a2018-07-03 10:40:40 +02001707 EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.ssrc), kTimeout);
1708 EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.ssrc), kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001709 EXPECT_EQ(1, NumSentSsrcs());
1710 EXPECT_EQ(0, NumRtpPackets(kSsrc));
1711 EXPECT_EQ(0, NumRtpBytes(kSsrc));
srtee0c2eea2017-12-15 17:44:33 +01001712}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001713
Niels Möller6557d0c2018-04-11 15:18:34 +02001714// Test that we can set the default video renderer before and after
1715// media is received.
srtee0c2eea2017-12-15 17:44:33 +01001716TEST_F(WebRtcVideoChannelBaseTest, SetSink) {
Yves Gerey665174f2018-06-19 15:03:05 +02001717 uint8_t data1[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
1718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Niels Möller6557d0c2018-04-11 15:18:34 +02001719
1720 rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
1721 rtc::SetBE32(packet1.data() + 8, kSsrc);
1722 channel_->SetSink(kDefaultReceiveSsrc, NULL);
1723 EXPECT_TRUE(SetDefaultCodec());
1724 EXPECT_TRUE(SetSend(true));
1725 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möllere6933812018-11-05 13:01:41 +01001726 channel_->OnPacketReceived(&packet1, /* packet_time_us */ -1);
Niels Möller6557d0c2018-04-11 15:18:34 +02001727 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
Niels Möller805a27e2019-01-21 12:21:27 +01001728 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001729 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
srtee0c2eea2017-12-15 17:44:33 +01001730}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001731
Niels Möller6557d0c2018-04-11 15:18:34 +02001732// Tests setting up and configuring a send stream.
srtee0c2eea2017-12-15 17:44:33 +01001733TEST_F(WebRtcVideoChannelBaseTest, AddRemoveSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001734 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1735 EXPECT_TRUE(SetSend(true));
1736 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
Niels Möller805a27e2019-01-21 12:21:27 +01001737 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001738 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1739 EXPECT_GT(NumRtpPackets(), 0);
Åsa Persson23cd45a2018-07-03 10:40:40 +02001740 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02001741 size_t last_packet = NumRtpPackets() - 1;
Yves Gerey665174f2018-06-19 15:03:05 +02001742 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(
1743 GetRtpPacket(static_cast<int>(last_packet)));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001744 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1745 EXPECT_EQ(kSsrc, header.ssrc);
Niels Möller6557d0c2018-04-11 15:18:34 +02001746
1747 // Remove the send stream that was added during Setup.
1748 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1749 int rtp_packets = NumRtpPackets();
1750
Niels Möller6557d0c2018-04-11 15:18:34 +02001751 EXPECT_TRUE(
Yves Gerey665174f2018-06-19 15:03:05 +02001752 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(789u)));
Niels Möller805a27e2019-01-21 12:21:27 +01001753 EXPECT_TRUE(channel_->SetVideoSend(789u, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001754 EXPECT_EQ(rtp_packets, NumRtpPackets());
1755 // Wait 30ms to guarantee the engine does not drop the frame.
1756 EXPECT_TRUE(WaitAndSendFrame(30));
1757 EXPECT_TRUE_WAIT(NumRtpPackets() > rtp_packets, kTimeout);
1758
1759 last_packet = NumRtpPackets() - 1;
1760 p.reset(GetRtpPacket(static_cast<int>(last_packet)));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001761 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1762 EXPECT_EQ(789u, header.ssrc);
srtee0c2eea2017-12-15 17:44:33 +01001763}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001764
Niels Möller6557d0c2018-04-11 15:18:34 +02001765// Tests the behavior of incoming streams in a conference scenario.
srtee0c2eea2017-12-15 17:44:33 +01001766TEST_F(WebRtcVideoChannelBaseTest, SimulateConference) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001767 cricket::FakeVideoRenderer renderer1, renderer2;
1768 EXPECT_TRUE(SetDefaultCodec());
1769 cricket::VideoSendParameters parameters;
1770 parameters.codecs.push_back(DefaultCodec());
1771 parameters.conference_mode = true;
1772 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1773 EXPECT_TRUE(SetSend(true));
Yves Gerey665174f2018-06-19 15:03:05 +02001774 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1775 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001776 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
1777 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
1778 EXPECT_EQ(0, renderer1.num_rendered_frames());
1779 EXPECT_EQ(0, renderer2.num_rendered_frames());
1780 std::vector<uint32_t> ssrcs;
1781 ssrcs.push_back(1);
1782 ssrcs.push_back(2);
1783 network_interface_.SetConferenceMode(true, ssrcs);
Niels Möller805a27e2019-01-21 12:21:27 +01001784 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001785 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight,
1786 kTimeout);
1787 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight,
1788 kTimeout);
1789
1790 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1791 EXPECT_EQ(DefaultCodec().id, GetPayloadType(p.get()));
1792 EXPECT_EQ(kVideoWidth, renderer1.width());
1793 EXPECT_EQ(kVideoHeight, renderer1.height());
1794 EXPECT_EQ(kVideoWidth, renderer2.width());
1795 EXPECT_EQ(kVideoHeight, renderer2.height());
1796 EXPECT_TRUE(channel_->RemoveRecvStream(2));
1797 EXPECT_TRUE(channel_->RemoveRecvStream(1));
srtee0c2eea2017-12-15 17:44:33 +01001798}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001799
Niels Möller6557d0c2018-04-11 15:18:34 +02001800// Tests that we can add and remove capturers and frames are sent out properly
srtee0c2eea2017-12-15 17:44:33 +01001801TEST_F(WebRtcVideoChannelBaseTest, DISABLED_AddRemoveCapturer) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001802 using cricket::VideoCodec;
1803 using cricket::VideoOptions;
1804 using cricket::VideoFormat;
1805 using cricket::FOURCC_I420;
1806
1807 VideoCodec codec = DefaultCodec();
1808 const int time_between_send_ms = VideoFormat::FpsToInterval(kFramerate);
1809 EXPECT_TRUE(SetOneCodec(codec));
1810 EXPECT_TRUE(SetSend(true));
1811 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1812 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01001813 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001814 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
Niels Möller805a27e2019-01-21 12:21:27 +01001815
1816 webrtc::test::FrameForwarder frame_forwarder;
1817 cricket::FakeFrameSource frame_source(480, 360, rtc::kNumMicrosecsPerSec / 30,
1818 rtc::kNumMicrosecsPerSec / 30);
Niels Möller6557d0c2018-04-11 15:18:34 +02001819
1820 // TODO(nisse): This testcase fails if we don't configure
1821 // screencast. It's unclear why, I see nothing obvious in this
1822 // test which is related to screencast logic.
1823 VideoOptions video_options;
1824 video_options.is_screencast = true;
1825 channel_->SetVideoSend(kSsrc, &video_options, nullptr);
1826
Niels Möller6557d0c2018-04-11 15:18:34 +02001827 int captured_frames = 1;
1828 for (int iterations = 0; iterations < 2; ++iterations) {
Niels Möller805a27e2019-01-21 12:21:27 +01001829 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
Niels Möller6557d0c2018-04-11 15:18:34 +02001830 rtc::Thread::Current()->ProcessMessages(time_between_send_ms);
Niels Möller805a27e2019-01-21 12:21:27 +01001831 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
1832
Niels Möller6557d0c2018-04-11 15:18:34 +02001833 ++captured_frames;
1834 // Wait until frame of right size is captured.
1835 EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
Niels Möller805a27e2019-01-21 12:21:27 +01001836 480 == renderer_.width() &&
1837 360 == renderer_.height() && !renderer_.black_frame(),
Yves Gerey665174f2018-06-19 15:03:05 +02001838 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001839 EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
Niels Möller805a27e2019-01-21 12:21:27 +01001840 EXPECT_EQ(480, renderer_.width());
1841 EXPECT_EQ(360, renderer_.height());
Niels Möller6557d0c2018-04-11 15:18:34 +02001842 captured_frames = renderer_.num_rendered_frames() + 1;
1843 EXPECT_FALSE(renderer_.black_frame());
1844 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
1845 // Make sure a black frame is generated within the specified timeout.
1846 // The black frame should be the resolution of the previous frame to
1847 // prevent expensive encoder reconfigurations.
1848 EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
Niels Möller805a27e2019-01-21 12:21:27 +01001849 480 == renderer_.width() &&
1850 360 == renderer_.height() && renderer_.black_frame(),
Yves Gerey665174f2018-06-19 15:03:05 +02001851 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001852 EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
Niels Möller805a27e2019-01-21 12:21:27 +01001853 EXPECT_EQ(480, renderer_.width());
1854 EXPECT_EQ(360, renderer_.height());
Niels Möller6557d0c2018-04-11 15:18:34 +02001855 EXPECT_TRUE(renderer_.black_frame());
1856
1857 // The black frame has the same timestamp as the next frame since it's
1858 // timestamp is set to the last frame's timestamp + interval. WebRTC will
1859 // not render a frame with the same timestamp so capture another frame
1860 // with the frame capturer to increment the next frame's timestamp.
Niels Möller805a27e2019-01-21 12:21:27 +01001861 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02001862 }
srtee0c2eea2017-12-15 17:44:33 +01001863}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001864
Niels Möller6557d0c2018-04-11 15:18:34 +02001865// Tests that if SetVideoSend is called with a NULL capturer after the
1866// capturer was already removed, the application doesn't crash (and no black
1867// frame is sent).
srtee0c2eea2017-12-15 17:44:33 +01001868TEST_F(WebRtcVideoChannelBaseTest, RemoveCapturerWithoutAdd) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001869 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1870 EXPECT_TRUE(SetSend(true));
1871 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1872 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01001873 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001874 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1875 // Wait for one frame so they don't get dropped because we send frames too
1876 // tightly.
1877 rtc::Thread::Current()->ProcessMessages(30);
1878 // Remove the capturer.
1879 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
1880
1881 // No capturer was added, so this SetVideoSend shouldn't do anything.
1882 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
1883 rtc::Thread::Current()->ProcessMessages(300);
1884 // Verify no more frames were sent.
1885 EXPECT_EQ(1, renderer_.num_rendered_frames());
srtee0c2eea2017-12-15 17:44:33 +01001886}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001887
Niels Möller6557d0c2018-04-11 15:18:34 +02001888// Tests that we can add and remove capturer as unique sources.
srtee0c2eea2017-12-15 17:44:33 +01001889TEST_F(WebRtcVideoChannelBaseTest, AddRemoveCapturerMultipleSources) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001890 // WebRTC implementation will drop frames if pushed to quickly. Wait the
1891 // interval time to avoid that.
1892 // WebRTC implementation will drop frames if pushed to quickly. Wait the
1893 // interval time to avoid that.
1894 // Set up the stream associated with the engine.
Yves Gerey665174f2018-06-19 15:03:05 +02001895 EXPECT_TRUE(
1896 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001897 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1898 cricket::VideoFormat capture_format(
1899 kVideoWidth, kVideoHeight,
1900 cricket::VideoFormat::FpsToInterval(kFramerate), cricket::FOURCC_I420);
1901 // Set up additional stream 1.
1902 cricket::FakeVideoRenderer renderer1;
1903 EXPECT_FALSE(channel_->SetSink(1, &renderer1));
Yves Gerey665174f2018-06-19 15:03:05 +02001904 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001905 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
Yves Gerey665174f2018-06-19 15:03:05 +02001906 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
Niels Möller805a27e2019-01-21 12:21:27 +01001907
1908 webrtc::test::FrameForwarder frame_forwarder1;
1909 cricket::FakeFrameSource frame_source(kVideoWidth, kVideoHeight,
1910 rtc::kNumMicrosecsPerSec / kFramerate);
1911
Niels Möller6557d0c2018-04-11 15:18:34 +02001912 // Set up additional stream 2.
1913 cricket::FakeVideoRenderer renderer2;
1914 EXPECT_FALSE(channel_->SetSink(2, &renderer2));
Yves Gerey665174f2018-06-19 15:03:05 +02001915 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001916 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
Yves Gerey665174f2018-06-19 15:03:05 +02001917 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller805a27e2019-01-21 12:21:27 +01001918 webrtc::test::FrameForwarder frame_forwarder2;
1919
Niels Möller6557d0c2018-04-11 15:18:34 +02001920 // State for all the streams.
1921 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1922 // A limitation in the lmi implementation requires that SetVideoSend() is
1923 // called after SetOneCodec().
1924 // TODO(hellner): this seems like an unnecessary constraint, fix it.
Niels Möller805a27e2019-01-21 12:21:27 +01001925 EXPECT_TRUE(channel_->SetVideoSend(1, nullptr, &frame_forwarder1));
1926 EXPECT_TRUE(channel_->SetVideoSend(2, nullptr, &frame_forwarder2));
Niels Möller6557d0c2018-04-11 15:18:34 +02001927 EXPECT_TRUE(SetSend(true));
1928 // Test capturer associated with engine.
1929 const int kTestWidth = 160;
1930 const int kTestHeight = 120;
Niels Möller805a27e2019-01-21 12:21:27 +01001931 frame_forwarder1.IncomingCapturedFrame(frame_source.GetFrame(
1932 kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0,
1933 rtc::kNumMicrosecsPerSec / kFramerate));
Yves Gerey665174f2018-06-19 15:03:05 +02001934 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kTestWidth, kTestHeight,
1935 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001936 // Capture a frame with additional capturer2, frames should be received
Niels Möller805a27e2019-01-21 12:21:27 +01001937 frame_forwarder2.IncomingCapturedFrame(frame_source.GetFrame(
1938 kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0,
1939 rtc::kNumMicrosecsPerSec / kFramerate));
Yves Gerey665174f2018-06-19 15:03:05 +02001940 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight,
1941 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001942 // Successfully remove the capturer.
1943 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
1944 // The capturers must be unregistered here as it runs out of it's scope
1945 // next.
1946 EXPECT_TRUE(channel_->SetVideoSend(1, nullptr, nullptr));
1947 EXPECT_TRUE(channel_->SetVideoSend(2, nullptr, nullptr));
srtee0c2eea2017-12-15 17:44:33 +01001948}
Niels Möller6557d0c2018-04-11 15:18:34 +02001949
1950// Tests empty StreamParams is rejected.
srtee0c2eea2017-12-15 17:44:33 +01001951TEST_F(WebRtcVideoChannelBaseTest, RejectEmptyStreamParams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001952 // Remove the send stream that was added during Setup.
1953 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1954
1955 cricket::StreamParams empty;
1956 EXPECT_FALSE(channel_->AddSendStream(empty));
Yves Gerey665174f2018-06-19 15:03:05 +02001957 EXPECT_TRUE(
1958 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(789u)));
srtee0c2eea2017-12-15 17:44:33 +01001959}
Niels Möller6557d0c2018-04-11 15:18:34 +02001960
1961// Test that multiple send streams can be created and deleted properly.
srtee0c2eea2017-12-15 17:44:33 +01001962TEST_F(WebRtcVideoChannelBaseTest, MultipleSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001963 // Remove stream added in Setup. I.e. remove stream corresponding to default
1964 // channel.
1965 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02001966 const unsigned int kSsrcsSize = sizeof(kSsrcs4) / sizeof(kSsrcs4[0]);
Niels Möller6557d0c2018-04-11 15:18:34 +02001967 for (unsigned int i = 0; i < kSsrcsSize; ++i) {
1968 EXPECT_TRUE(channel_->AddSendStream(
1969 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1970 }
1971 // Delete one of the non default channel streams, let the destructor delete
1972 // the remaining ones.
1973 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
1974 // Stream should already be deleted.
1975 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
srtee0c2eea2017-12-15 17:44:33 +01001976}
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +00001977
eladalonf1841382017-06-12 01:16:46 -07001978TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Vga) {
magjed509e4fe2016-11-18 01:34:11 -08001979 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00001980}
1981
eladalonf1841382017-06-12 01:16:46 -07001982TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Qvga) {
magjed509e4fe2016-11-18 01:34:11 -08001983 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00001984}
1985
eladalonf1841382017-06-12 01:16:46 -07001986TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8SvcQqvga) {
magjed509e4fe2016-11-18 01:34:11 -08001987 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00001988}
1989
eladalonf1841382017-06-12 01:16:46 -07001990TEST_F(WebRtcVideoChannelBaseTest, TwoStreamsSendAndReceive) {
Peter Boströmd1f584b2016-04-20 16:31:53 +02001991 // Set a high bitrate to not be downscaled by VP8 due to low initial start
1992 // bitrates. This currently happens at <250k, and two streams sharing 300k
1993 // initially will use QVGA instead of VGA.
1994 // TODO(pbos): Set up the quality scaler so that both senders reliably start
1995 // at QVGA, then verify that instead.
magjed509e4fe2016-11-18 01:34:11 -08001996 cricket::VideoCodec codec = GetEngineCodec("VP8");
Peter Boströmd1f584b2016-04-20 16:31:53 +02001997 codec.params[kCodecParamStartBitrate] = "1000000";
Niels Möller6557d0c2018-04-11 15:18:34 +02001998 TwoStreamsSendAndReceive(codec);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001999}
2000
eladalonf1841382017-06-12 01:16:46 -07002001class WebRtcVideoChannelTest : public WebRtcVideoEngineTest {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002002 public:
eladalonf1841382017-06-12 01:16:46 -07002003 WebRtcVideoChannelTest() : WebRtcVideoChannelTest("") {}
2004 explicit WebRtcVideoChannelTest(const char* field_trials)
Niels Möller805a27e2019-01-21 12:21:27 +01002005 : WebRtcVideoEngineTest(field_trials),
2006 frame_source_(1280, 720, rtc::kNumMicrosecsPerSec / 30),
2007 last_ssrc_(0) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002008 void SetUp() override {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02002009 encoder_factory_->AddSupportedVideoCodecType("VP8");
2010 encoder_factory_->AddSupportedVideoCodecType("VP9");
2011#if defined(WEBRTC_USE_H264)
2012 encoder_factory_->AddSupportedVideoCodecType("H264");
2013#endif
2014
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002015 fake_call_.reset(new FakeCall());
Sebastian Jansson84848f22018-11-16 10:40:36 +01002016 channel_.reset(engine_.CreateMediaChannel(fake_call_.get(),
2017 GetMediaConfig(), VideoOptions(),
2018 webrtc::CryptoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002019 channel_->OnReadyToSend(true);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002020 last_ssrc_ = 123;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002021 send_parameters_.codecs = engine_.codecs();
2022 recv_parameters_.codecs = engine_.codecs();
2023 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002024 }
2025
2026 protected:
2027 FakeVideoSendStream* AddSendStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002028 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002029 }
2030
2031 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002032 size_t num_streams = fake_call_->GetVideoSendStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002033 EXPECT_TRUE(channel_->AddSendStream(sp));
2034 std::vector<FakeVideoSendStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002035 fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002036 EXPECT_EQ(num_streams + 1, streams.size());
2037 return streams[streams.size() - 1];
2038 }
2039
2040 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002041 return fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002042 }
2043
2044 FakeVideoReceiveStream* AddRecvStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002045 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002046 }
2047
2048 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002049 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002050 EXPECT_TRUE(channel_->AddRecvStream(sp));
2051 std::vector<FakeVideoReceiveStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002052 fake_call_->GetVideoReceiveStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002053 EXPECT_EQ(num_streams + 1, streams.size());
2054 return streams[streams.size() - 1];
2055 }
2056
pbos@webrtc.org00873182014-11-25 14:03:34 +00002057 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
2058 int expected_min_bitrate_bps,
2059 const char* start_bitrate_kbps,
2060 int expected_start_bitrate_bps,
2061 const char* max_bitrate_kbps,
2062 int expected_max_bitrate_bps) {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002063 ExpectSetBitrateParameters(expected_min_bitrate_bps,
2064 expected_start_bitrate_bps,
2065 expected_max_bitrate_bps);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002066 auto& codecs = send_parameters_.codecs;
2067 codecs.clear();
magjed509e4fe2016-11-18 01:34:11 -08002068 codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org00873182014-11-25 14:03:34 +00002069 codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps;
2070 codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps;
2071 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002072 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002073 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002074
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002075 void ExpectSetBitrateParameters(int min_bitrate_bps,
2076 int start_bitrate_bps,
2077 int max_bitrate_bps) {
2078 EXPECT_CALL(
2079 *fake_call_->GetMockTransportControllerSend(),
2080 SetSdpBitrateParameters(AllOf(
2081 Field(&BitrateConstraints::min_bitrate_bps, min_bitrate_bps),
2082 Field(&BitrateConstraints::start_bitrate_bps, start_bitrate_bps),
2083 Field(&BitrateConstraints::max_bitrate_bps, max_bitrate_bps))));
2084 }
2085
2086 void ExpectSetMaxBitrate(int max_bitrate_bps) {
2087 EXPECT_CALL(*fake_call_->GetMockTransportControllerSend(),
2088 SetSdpBitrateParameters(Field(
2089 &BitrateConstraints::max_bitrate_bps, max_bitrate_bps)));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002090 }
2091
Johannes Kron9190b822018-10-29 11:22:05 +01002092 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
2093 // For a caller, the answer will be applied in set remote description
2094 // where SetSendParameters() is called.
2095 EXPECT_TRUE(
2096 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
2097 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
2098 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2099 const webrtc::VideoSendStream::Config& config =
2100 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2101 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
2102 }
2103
2104 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
2105 // For a callee, the answer will be applied in set local description
2106 // where SetExtmapAllowMixed() and AddSendStream() are called.
2107 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
2108 EXPECT_TRUE(
2109 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
2110 const webrtc::VideoSendStream::Config& config =
2111 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2112 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
2113 }
2114
isheriff6f8d6862016-05-26 11:24:55 -07002115 void TestSetSendRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002116 // Enable extension.
2117 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002118 cricket::VideoSendParameters parameters = send_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07002119 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002120 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002121 FakeVideoSendStream* send_stream =
2122 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2123
2124 // Verify the send extension id.
2125 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2126 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002127 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002128 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002129 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002130 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
2131 // receivers.
2132 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
2133 ->GetConfig()
2134 .rtp.extensions.empty());
2135
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002136 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002137 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002138 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2139 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002140 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
2141
2142 // Verify that adding receive RTP header extensions adds them for existing
2143 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002144 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002145 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002146 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2147 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002148 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002149 }
2150
isheriff6f8d6862016-05-26 11:24:55 -07002151 void TestSetRecvRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002152 // Enable extension.
2153 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002154 cricket::VideoRecvParameters parameters = recv_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07002155 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002156 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002157
2158 FakeVideoReceiveStream* recv_stream =
2159 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2160
2161 // Verify the recv extension id.
2162 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
2163 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002164 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002165 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002166 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002167
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002168 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
2169 // senders.
2170 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
2171 ->GetConfig()
2172 .rtp.extensions.empty());
2173
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002174 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002175 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002176 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
2177 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002178 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
2179
2180 // Verify that adding receive RTP header extensions adds them for existing
2181 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002182 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002183 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002184 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
2185 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002186 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002187 }
2188
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002189 void TestExtensionFilter(const std::vector<std::string>& extensions,
2190 const std::string& expected_extension) {
2191 cricket::VideoSendParameters parameters = send_parameters_;
2192 int expected_id = -1;
2193 int id = 1;
2194 for (const std::string& extension : extensions) {
2195 if (extension == expected_extension)
2196 expected_id = id;
isheriff6f8d6862016-05-26 11:24:55 -07002197 parameters.extensions.push_back(RtpExtension(extension, id++));
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002198 }
2199 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2200 FakeVideoSendStream* send_stream =
2201 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2202
2203 // Verify that only one of them has been set, and that it is the one with
2204 // highest priority (transport sequence number).
2205 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2206 EXPECT_EQ(expected_id, send_stream->GetConfig().rtp.extensions[0].id);
2207 EXPECT_EQ(expected_extension,
isheriff6f8d6862016-05-26 11:24:55 -07002208 send_stream->GetConfig().rtp.extensions[0].uri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002209 }
2210
asapersson3c81a1a2017-06-14 05:52:21 -07002211 void TestDegradationPreference(bool resolution_scaling_enabled,
2212 bool fps_scaling_enabled);
2213
Erik Språngefbde372015-04-29 16:21:28 +02002214 void TestCpuAdaptation(bool enable_overuse, bool is_screenshare);
Peter Boström3548dd22015-05-22 18:48:36 +02002215 void TestReceiverLocalSsrcConfiguration(bool receiver_first);
magjed509e4fe2016-11-18 01:34:11 -08002216 void TestReceiveUnsignaledSsrcPacket(uint8_t payload_type,
2217 bool expect_created_receive_stream);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002218
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002219 FakeVideoSendStream* SetDenoisingOption(
nisse05103312016-03-16 02:22:50 -07002220 uint32_t ssrc,
Niels Möller805a27e2019-01-21 12:21:27 +01002221 webrtc::test::FrameForwarder* frame_forwarder,
nisse0db023a2016-03-01 04:29:59 -08002222 bool enabled) {
nisse05103312016-03-16 02:22:50 -07002223 cricket::VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002224 options.video_noise_reduction = enabled;
Niels Möller805a27e2019-01-21 12:21:27 +01002225 EXPECT_TRUE(channel_->SetVideoSend(ssrc, &options, frame_forwarder));
nisse0db023a2016-03-01 04:29:59 -08002226 // Options only take effect on the next frame.
Niels Möller805a27e2019-01-21 12:21:27 +01002227 frame_forwarder->IncomingCapturedFrame(frame_source_.GetFrame());
nisse0db023a2016-03-01 04:29:59 -08002228
Erik Språng143cec12015-04-28 10:01:41 +02002229 return fake_call_->GetVideoSendStreams().back();
2230 }
2231
Peter Boström2feafdb2015-09-09 14:32:14 +02002232 FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) {
2233 const int kRtxSsrcOffset = 0xDEADBEEF;
Erik Språng143cec12015-04-28 10:01:41 +02002234 last_ssrc_ += 3;
Peter Boström2feafdb2015-09-09 14:32:14 +02002235 std::vector<uint32_t> ssrcs;
2236 std::vector<uint32_t> rtx_ssrcs;
2237 uint32_t num_streams = enabled ? 3 : 1;
2238 for (uint32_t i = 0; i < num_streams; ++i) {
2239 uint32_t ssrc = last_ssrc_ + i;
2240 ssrcs.push_back(ssrc);
2241 if (with_rtx) {
2242 rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset);
2243 }
Erik Språng143cec12015-04-28 10:01:41 +02002244 }
Peter Boström2feafdb2015-09-09 14:32:14 +02002245 if (with_rtx) {
2246 return AddSendStream(
2247 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
2248 }
2249 return AddSendStream(CreateSimStreamParams("cname", ssrcs));
Erik Språng143cec12015-04-28 10:01:41 +02002250 }
2251
perkjfa10b552016-10-02 23:45:26 -07002252 int GetMaxEncoderBitrate() {
skvladdc1c62c2016-03-16 19:07:43 -07002253 std::vector<FakeVideoSendStream*> streams =
2254 fake_call_->GetVideoSendStreams();
perkjfa10b552016-10-02 23:45:26 -07002255 EXPECT_EQ(1u, streams.size());
skvladdc1c62c2016-03-16 19:07:43 -07002256 FakeVideoSendStream* stream = streams[streams.size() - 1];
Mirko Bonadeif859e552018-05-30 15:31:29 +02002257 EXPECT_EQ(1u, stream->GetEncoderConfig().number_of_streams);
perkjfa10b552016-10-02 23:45:26 -07002258 return stream->GetVideoStreams()[0].max_bitrate_bps;
skvladdc1c62c2016-03-16 19:07:43 -07002259 }
2260
perkjfa10b552016-10-02 23:45:26 -07002261 void SetAndExpectMaxBitrate(int global_max,
skvladdc1c62c2016-03-16 19:07:43 -07002262 int stream_max,
2263 int expected_encoder_bitrate) {
2264 VideoSendParameters limited_send_params = send_parameters_;
2265 limited_send_params.max_bandwidth_bps = global_max;
2266 EXPECT_TRUE(channel_->SetSendParameters(limited_send_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07002267 webrtc::RtpParameters parameters =
2268 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07002269 EXPECT_EQ(1UL, parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01002270 parameters.encodings[0].max_bitrate_bps = stream_max;
Zach Steinba37b4b2018-01-23 15:02:36 -08002271 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07002272 // Read back the parameteres and verify they have the correct value
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07002273 parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07002274 EXPECT_EQ(1UL, parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01002275 EXPECT_EQ(stream_max, parameters.encodings[0].max_bitrate_bps);
skvladdc1c62c2016-03-16 19:07:43 -07002276 // Verify that the new value propagated down to the encoder
perkjfa10b552016-10-02 23:45:26 -07002277 EXPECT_EQ(expected_encoder_bitrate, GetMaxEncoderBitrate());
skvladdc1c62c2016-03-16 19:07:43 -07002278 }
2279
Åsa Persson55659812018-06-18 17:51:32 +02002280 // Values from kSimulcastConfigs in simulcast.cc.
2281 const std::vector<webrtc::VideoStream> GetSimulcastBitrates720p() const {
2282 std::vector<webrtc::VideoStream> layers(3);
2283 layers[0].min_bitrate_bps = 30000;
2284 layers[0].target_bitrate_bps = 150000;
2285 layers[0].max_bitrate_bps = 200000;
2286 layers[1].min_bitrate_bps = 150000;
2287 layers[1].target_bitrate_bps = 500000;
2288 layers[1].max_bitrate_bps = 700000;
2289 layers[2].min_bitrate_bps = 600000;
2290 layers[2].target_bitrate_bps = 2500000;
2291 layers[2].max_bitrate_bps = 2500000;
2292 return layers;
2293 }
2294
Niels Möller805a27e2019-01-21 12:21:27 +01002295 cricket::FakeFrameSource frame_source_;
kwiberg686a8ef2016-02-26 03:00:35 -08002296 std::unique_ptr<FakeCall> fake_call_;
2297 std::unique_ptr<VideoMediaChannel> channel_;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002298 cricket::VideoSendParameters send_parameters_;
2299 cricket::VideoRecvParameters recv_parameters_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02002300 uint32_t last_ssrc_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002301};
2302
eladalonf1841382017-06-12 01:16:46 -07002303TEST_F(WebRtcVideoChannelTest, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02002304 const uint32_t kVideoSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07002305 const std::string kSyncLabel = "AvSyncLabel";
2306
2307 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08002308 sp.set_stream_ids({kSyncLabel});
pbos8fc7fa72015-07-15 08:02:58 -07002309 EXPECT_TRUE(channel_->AddRecvStream(sp));
2310
Mirko Bonadeif859e552018-05-30 15:31:29 +02002311 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07002312 EXPECT_EQ(kSyncLabel,
2313 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group)
2314 << "SyncGroup should be set based on sync_label";
2315}
2316
eladalonf1841382017-06-12 01:16:46 -07002317TEST_F(WebRtcVideoChannelTest, RecvStreamWithSimAndRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002318 cricket::VideoSendParameters parameters;
2319 parameters.codecs = engine_.codecs();
2320 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002321 EXPECT_TRUE(channel_->SetSend(true));
nisse4b4dc862016-02-17 05:25:36 -08002322 parameters.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002323 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002324
2325 // Send side.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002326 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
2327 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002328 FakeVideoSendStream* send_stream = AddSendStream(
2329 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
2330
2331 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
2332 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
2333 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
2334
2335 // Receiver side.
2336 FakeVideoReceiveStream* recv_stream = AddRecvStream(
2337 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
nisse26e3abb2017-08-25 04:44:25 -07002338 EXPECT_FALSE(
2339 recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
nisseca5706d2017-09-11 02:32:16 -07002340 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
Peter Boströmd8b01092016-05-12 16:44:36 +02002341 << "RTX should be mapped for all decoders/payload types.";
nisseca5706d2017-09-11 02:32:16 -07002342 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02002343 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07002344 << "RTX should be mapped for the RED payload type";
2345
brandtr14742122017-01-27 04:53:07 -08002346 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002347}
2348
eladalonf1841382017-06-12 01:16:46 -07002349TEST_F(WebRtcVideoChannelTest, RecvStreamWithRtx) {
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002350 // Setup one channel with an associated RTX stream.
2351 cricket::StreamParams params =
2352 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2353 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
2354 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
brandtr14742122017-01-27 04:53:07 -08002355 EXPECT_EQ(kRtxSsrcs1[0], recv_stream->GetConfig().rtp.rtx_ssrc);
nisseca5706d2017-09-11 02:32:16 -07002356
2357 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
2358 << "RTX should be mapped for all decoders/payload types.";
2359 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02002360 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07002361 << "RTX should be mapped for the RED payload type";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002362}
2363
eladalonf1841382017-06-12 01:16:46 -07002364TEST_F(WebRtcVideoChannelTest, RecvStreamNoRtx) {
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002365 // Setup one channel without an associated RTX stream.
2366 cricket::StreamParams params =
2367 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2368 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
brandtr14742122017-01-27 04:53:07 -08002369 ASSERT_EQ(0U, recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002370}
2371
Johannes Kron9190b822018-10-29 11:22:05 +01002372// Test propagation of extmap allow mixed setting.
2373TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCaller) {
2374 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2375}
2376TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCaller) {
2377 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2378}
2379TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCallee) {
2380 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2381}
2382TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCallee) {
2383 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2384}
2385
eladalonf1841382017-06-12 01:16:46 -07002386TEST_F(WebRtcVideoChannelTest, NoHeaderExtesionsByDefault) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002387 FakeVideoSendStream* send_stream =
2388 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
2389 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
2390
2391 FakeVideoReceiveStream* recv_stream =
2392 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
2393 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002394}
2395
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002396// Test support for RTP timestamp offset header extension.
eladalonf1841382017-06-12 01:16:46 -07002397TEST_F(WebRtcVideoChannelTest, SendRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002398 TestSetSendRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002399}
isheriff6f8d6862016-05-26 11:24:55 -07002400
eladalonf1841382017-06-12 01:16:46 -07002401TEST_F(WebRtcVideoChannelTest, RecvRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002402 TestSetRecvRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002403}
2404
2405// Test support for absolute send time header extension.
eladalonf1841382017-06-12 01:16:46 -07002406TEST_F(WebRtcVideoChannelTest, SendAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002407 TestSetSendRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002408}
isheriff6f8d6862016-05-26 11:24:55 -07002409
eladalonf1841382017-06-12 01:16:46 -07002410TEST_F(WebRtcVideoChannelTest, RecvAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002411 TestSetRecvRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002412}
2413
eladalonf1841382017-06-12 01:16:46 -07002414TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksTransportSeqNum) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002415 // Enable three redundant extensions.
2416 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07002417 extensions.push_back(RtpExtension::kAbsSendTimeUri);
2418 extensions.push_back(RtpExtension::kTimestampOffsetUri);
2419 extensions.push_back(RtpExtension::kTransportSequenceNumberUri);
2420 TestExtensionFilter(extensions, RtpExtension::kTransportSequenceNumberUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002421}
2422
eladalonf1841382017-06-12 01:16:46 -07002423TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksAbsSendTime) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002424 // Enable two redundant extensions.
2425 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07002426 extensions.push_back(RtpExtension::kAbsSendTimeUri);
2427 extensions.push_back(RtpExtension::kTimestampOffsetUri);
2428 TestExtensionFilter(extensions, RtpExtension::kAbsSendTimeUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002429}
2430
stefanc1aeaf02015-10-15 07:26:07 -07002431// Test support for transport sequence number header extension.
eladalonf1841382017-06-12 01:16:46 -07002432TEST_F(WebRtcVideoChannelTest, SendTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002433 TestSetSendRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07002434}
eladalonf1841382017-06-12 01:16:46 -07002435TEST_F(WebRtcVideoChannelTest, RecvTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002436 TestSetRecvRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07002437}
2438
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002439// Test support for video rotation header extension.
eladalonf1841382017-06-12 01:16:46 -07002440TEST_F(WebRtcVideoChannelTest, SendVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002441 TestSetSendRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002442}
eladalonf1841382017-06-12 01:16:46 -07002443TEST_F(WebRtcVideoChannelTest, RecvVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002444 TestSetRecvRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002445}
2446
eladalonf1841382017-06-12 01:16:46 -07002447TEST_F(WebRtcVideoChannelTest, IdenticalSendExtensionsDoesntRecreateStream) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002448 const int kAbsSendTimeId = 1;
2449 const int kVideoRotationId = 2;
isheriff6f8d6862016-05-26 11:24:55 -07002450 send_parameters_.extensions.push_back(
2451 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
2452 send_parameters_.extensions.push_back(
2453 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002454
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002455 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002456 FakeVideoSendStream* send_stream =
2457 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2458
2459 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002460 ASSERT_EQ(2u, send_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002461
2462 // Setting the same extensions (even if in different order) shouldn't
2463 // reallocate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002464 std::reverse(send_parameters_.extensions.begin(),
2465 send_parameters_.extensions.end());
2466 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002467
2468 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2469
2470 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002471 send_parameters_.extensions.resize(1);
2472 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002473
2474 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
2475}
2476
eladalonf1841382017-06-12 01:16:46 -07002477TEST_F(WebRtcVideoChannelTest, IdenticalRecvExtensionsDoesntRecreateStream) {
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002478 const int kTOffsetId = 1;
2479 const int kAbsSendTimeId = 2;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002480 const int kVideoRotationId = 3;
isheriff6f8d6862016-05-26 11:24:55 -07002481 recv_parameters_.extensions.push_back(
2482 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
2483 recv_parameters_.extensions.push_back(
2484 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
2485 recv_parameters_.extensions.push_back(
2486 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002487
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002488 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Peter Boström54be3e02015-05-25 15:04:24 +02002489 FakeVideoReceiveStream* recv_stream =
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002490 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2491
2492 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Peter Boström54be3e02015-05-25 15:04:24 +02002493 ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002494
2495 // Setting the same extensions (even if in different order) shouldn't
2496 // reallocate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002497 std::reverse(recv_parameters_.extensions.begin(),
2498 recv_parameters_.extensions.end());
2499 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002500
2501 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2502
2503 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002504 recv_parameters_.extensions.resize(1);
2505 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002506
2507 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
2508}
2509
eladalonf1841382017-06-12 01:16:46 -07002510TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002511 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002512 const int kUnsupportedId = 1;
2513 const int kTOffsetId = 2;
2514
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002515 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002516 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002517 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002518 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002519 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002520 FakeVideoSendStream* send_stream =
2521 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2522
2523 // Only timestamp offset extension is set to send stream,
2524 // unsupported rtp extension is ignored.
2525 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07002526 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
2527 send_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002528}
2529
eladalonf1841382017-06-12 01:16:46 -07002530TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002531 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002532 const int kUnsupportedId = 1;
2533 const int kTOffsetId = 2;
2534
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002535 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002536 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002537 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002538 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002539 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002540 FakeVideoReceiveStream* recv_stream =
2541 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2542
2543 // Only timestamp offset extension is set to receive stream,
2544 // unsupported rtp extension is ignored.
2545 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07002546 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
2547 recv_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002548}
2549
eladalonf1841382017-06-12 01:16:46 -07002550TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02002551 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002552 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07002553 send_parameters_.extensions.push_back(
2554 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002555 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002556 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
2557 }
2558}
2559
eladalonf1841382017-06-12 01:16:46 -07002560TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02002561 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002562 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07002563 recv_parameters_.extensions.push_back(
2564 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002565 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002566 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
2567 }
2568}
2569
eladalonf1841382017-06-12 01:16:46 -07002570TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002571 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002572 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002573 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002574 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002575 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002576 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002577
2578 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002579 send_parameters_.extensions.clear();
2580 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002581 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002582 send_parameters_.extensions.push_back(send_parameters_.extensions.back());
2583 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002584}
2585
eladalonf1841382017-06-12 01:16:46 -07002586TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002587 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002588 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002589 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002590 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002591 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002592 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002593
2594 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002595 recv_parameters_.extensions.clear();
2596 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002597 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002598 recv_parameters_.extensions.push_back(recv_parameters_.extensions.back());
2599 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002600}
2601
eladalonf1841382017-06-12 01:16:46 -07002602TEST_F(WebRtcVideoChannelTest, AddRecvStreamOnlyUsesOneReceiveStream) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002603 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002604 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002605}
2606
eladalonf1841382017-06-12 01:16:46 -07002607TEST_F(WebRtcVideoChannelTest, RtcpIsCompoundByDefault) {
Peter Boströmd7da1202015-06-05 14:09:38 +02002608 FakeVideoReceiveStream* stream = AddRecvStream();
pbosda903ea2015-10-02 02:36:56 -07002609 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream->GetConfig().rtp.rtcp_mode);
Peter Boströmd7da1202015-06-05 14:09:38 +02002610}
2611
eladalonf1841382017-06-12 01:16:46 -07002612TEST_F(WebRtcVideoChannelTest, RembIsEnabledByDefault) {
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002613 FakeVideoReceiveStream* stream = AddRecvStream();
2614 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002615}
2616
eladalonf1841382017-06-12 01:16:46 -07002617TEST_F(WebRtcVideoChannelTest, TransportCcIsEnabledByDefault) {
stefan43edf0f2015-11-20 18:05:48 -08002618 FakeVideoReceiveStream* stream = AddRecvStream();
2619 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
2620}
2621
eladalonf1841382017-06-12 01:16:46 -07002622TEST_F(WebRtcVideoChannelTest, RembCanBeEnabledAndDisabled) {
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002623 FakeVideoReceiveStream* stream = AddRecvStream();
2624 EXPECT_TRUE(stream->GetConfig().rtp.remb);
2625
Peter Boström126c03e2015-05-11 12:48:12 +02002626 // Verify that REMB is turned off when send(!) codecs without REMB are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002627 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002628 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002629 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
2630 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002631 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002632 EXPECT_FALSE(stream->GetConfig().rtp.remb);
2633
2634 // Verify that REMB is turned on when setting default codecs since the
2635 // default codecs have REMB enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002636 parameters.codecs = engine_.codecs();
2637 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002638 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002639 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002640}
2641
eladalonf1841382017-06-12 01:16:46 -07002642TEST_F(WebRtcVideoChannelTest, TransportCcCanBeEnabledAndDisabled) {
stefan43edf0f2015-11-20 18:05:48 -08002643 FakeVideoReceiveStream* stream = AddRecvStream();
2644 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
2645
2646 // Verify that transport cc feedback is turned off when send(!) codecs without
2647 // transport cc feedback are set.
2648 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002649 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
stefan43edf0f2015-11-20 18:05:48 -08002650 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
2651 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2652 stream = fake_call_->GetVideoReceiveStreams()[0];
2653 EXPECT_FALSE(stream->GetConfig().rtp.transport_cc);
2654
2655 // Verify that transport cc feedback is turned on when setting default codecs
2656 // since the default codecs have transport cc feedback enabled.
2657 parameters.codecs = engine_.codecs();
2658 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2659 stream = fake_call_->GetVideoReceiveStreams()[0];
2660 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
2661}
2662
eladalonf1841382017-06-12 01:16:46 -07002663TEST_F(WebRtcVideoChannelTest, NackIsEnabledByDefault) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02002664 AssignDefaultCodec();
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00002665 VerifyCodecHasDefaultFeedbackParams(default_codec_);
2666
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002667 cricket::VideoSendParameters parameters;
2668 parameters.codecs = engine_.codecs();
2669 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org19864742014-05-30 07:35:47 +00002670 EXPECT_TRUE(channel_->SetSend(true));
2671
2672 // Send side.
2673 FakeVideoSendStream* send_stream =
2674 AddSendStream(cricket::StreamParams::CreateLegacy(1));
2675 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2676
2677 // Receiver side.
2678 FakeVideoReceiveStream* recv_stream =
2679 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
2680 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2681
2682 // Nack history size should match between sender and receiver.
2683 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
2684 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002685}
2686
eladalonf1841382017-06-12 01:16:46 -07002687TEST_F(WebRtcVideoChannelTest, NackCanBeEnabledAndDisabled) {
Peter Boström67c9df72015-05-11 14:34:58 +02002688 FakeVideoSendStream* send_stream = AddSendStream();
Peter Boström3548dd22015-05-22 18:48:36 +02002689 FakeVideoReceiveStream* recv_stream = AddRecvStream();
Peter Boström67c9df72015-05-11 14:34:58 +02002690
2691 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2692 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2693
2694 // Verify that NACK is turned off when send(!) codecs without NACK are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002695 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002696 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002697 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
2698 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02002699 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
2700 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
2701 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00002702 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
2703
Peter Boström67c9df72015-05-11 14:34:58 +02002704 // Verify that NACK is turned on when setting default codecs since the
2705 // default codecs have NACK enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002706 parameters.codecs = engine_.codecs();
2707 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02002708 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
2709 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2710 send_stream = fake_call_->GetVideoSendStreams()[0];
2711 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00002712}
2713
Peter Boströme7ba0862016-03-12 00:02:28 +01002714// This test verifies that new frame sizes reconfigures encoders even though not
2715// (yet) sending. The purpose of this is to permit encoding as quickly as
2716// possible once we start sending. Likely the frames being input are from the
2717// same source that will be sent later, which just means that we're ready
2718// earlier.
eladalonf1841382017-06-12 01:16:46 -07002719TEST_F(WebRtcVideoChannelTest, ReconfiguresEncodersWhenNotSending) {
Peter Boströme7ba0862016-03-12 00:02:28 +01002720 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002721 parameters.codecs.push_back(GetEngineCodec("VP8"));
Peter Boströme7ba0862016-03-12 00:02:28 +01002722 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2723 channel_->SetSend(false);
2724
2725 FakeVideoSendStream* stream = AddSendStream();
2726
perkjfa10b552016-10-02 23:45:26 -07002727 // No frames entered.
Peter Boströme7ba0862016-03-12 00:02:28 +01002728 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
Danil Chapovalov350531e2018-06-08 11:04:04 +00002729 EXPECT_EQ(0u, streams[0].width);
2730 EXPECT_EQ(0u, streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01002731
Niels Möller805a27e2019-01-21 12:21:27 +01002732 webrtc::test::FrameForwarder frame_forwarder;
2733 cricket::FakeFrameSource frame_source(1280, 720,
2734 rtc::kNumMicrosecsPerSec / 30);
2735
2736 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
2737 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Peter Boströme7ba0862016-03-12 00:02:28 +01002738
2739 // Frame entered, should be reconfigured to new dimensions.
2740 streams = stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01002741 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams[0].width);
2742 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01002743
Niels Möllerff40b142018-04-09 08:49:14 +02002744 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boströme7ba0862016-03-12 00:02:28 +01002745}
2746
eladalonf1841382017-06-12 01:16:46 -07002747TEST_F(WebRtcVideoChannelTest, UsesCorrectSettingsForScreencast) {
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002748 static const int kScreenshareMinBitrateKbps = 800;
magjed509e4fe2016-11-18 01:34:11 -08002749 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002750 cricket::VideoSendParameters parameters;
2751 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002752 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002753 AddSendStream();
2754
Niels Möller805a27e2019-01-21 12:21:27 +01002755 webrtc::test::FrameForwarder frame_forwarder;
2756 cricket::FakeFrameSource frame_source(1280, 720,
2757 rtc::kNumMicrosecsPerSec / 30);
nisse05103312016-03-16 02:22:50 -07002758 VideoOptions min_bitrate_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002759 min_bitrate_options.screencast_min_bitrate_kbps = kScreenshareMinBitrateKbps;
Niels Möller805a27e2019-01-21 12:21:27 +01002760 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &min_bitrate_options,
2761 &frame_forwarder));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002762
2763 EXPECT_TRUE(channel_->SetSend(true));
2764
Niels Möller805a27e2019-01-21 12:21:27 +01002765 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002766 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2767 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
2768
2769 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2770
2771 // Verify non-screencast settings.
perkj26091b12016-09-01 01:17:40 -07002772 webrtc::VideoEncoderConfig encoder_config =
2773 send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02002774 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002775 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07002776 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01002777 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams.front().width);
2778 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams.front().height);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002779 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
2780 << "Non-screenshare shouldn't use min-transmit bitrate.";
2781
Niels Möllerff40b142018-04-09 08:49:14 +02002782 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
perkjd533aec2017-01-13 05:57:25 -08002783 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
nisse05103312016-03-16 02:22:50 -07002784 VideoOptions screencast_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002785 screencast_options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01002786 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &screencast_options,
2787 &frame_forwarder));
2788 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08002789 // Send stream recreated after option change.
2790 ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
2791 send_stream = fake_call_->GetVideoSendStreams().front();
2792 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002793
2794 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07002795 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02002796 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002797 encoder_config.content_type);
2798 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
2799 encoder_config.min_transmit_bitrate_bps);
2800
perkjfa10b552016-10-02 23:45:26 -07002801 streams = send_stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01002802 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams.front().width);
2803 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams.front().height);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002804 EXPECT_FALSE(streams[0].num_temporal_layers.has_value());
Niels Möllerff40b142018-04-09 08:49:14 +02002805 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002806}
2807
eladalonf1841382017-06-12 01:16:46 -07002808TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002809 ConferenceModeScreencastConfiguresTemporalLayer) {
Rasmus Brandt195d1d72018-05-09 11:28:01 +02002810 static const int kConferenceScreencastTemporalBitrateBps = 200 * 1000;
nisse4b4dc862016-02-17 05:25:36 -08002811 send_parameters_.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002812 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002813
2814 AddSendStream();
nisse05103312016-03-16 02:22:50 -07002815 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002816 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01002817 webrtc::test::FrameForwarder frame_forwarder;
2818 cricket::FakeFrameSource frame_source(1280, 720,
2819 rtc::kNumMicrosecsPerSec / 30);
2820 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002821 EXPECT_TRUE(channel_->SetSend(true));
2822
Niels Möller805a27e2019-01-21 12:21:27 +01002823 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002824 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2825 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
2826
perkj26091b12016-09-01 01:17:40 -07002827 webrtc::VideoEncoderConfig encoder_config =
2828 send_stream->GetEncoderConfig().Copy();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002829
2830 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07002831 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02002832 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002833 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07002834
2835 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
2836 ASSERT_EQ(1u, streams.size());
Sergey Silkina796a7e2018-03-01 15:11:29 +01002837 ASSERT_EQ(2u, streams[0].num_temporal_layers);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002838 EXPECT_EQ(kConferenceScreencastTemporalBitrateBps,
Sergey Silkina796a7e2018-03-01 15:11:29 +01002839 streams[0].target_bitrate_bps);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002840
Niels Möllerff40b142018-04-09 08:49:14 +02002841 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002842}
2843
eladalonf1841382017-06-12 01:16:46 -07002844TEST_F(WebRtcVideoChannelTest, SuspendBelowMinBitrateDisabledByDefault) {
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002845 FakeVideoSendStream* stream = AddSendStream();
2846 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
2847}
2848
eladalonf1841382017-06-12 01:16:46 -07002849TEST_F(WebRtcVideoChannelTest, SetMediaConfigSuspendBelowMinBitrate) {
kthelgason2bc68642017-02-07 07:02:22 -08002850 MediaConfig media_config = GetMediaConfig();
nisse0db023a2016-03-01 04:29:59 -08002851 media_config.video.suspend_below_min_bitrate = true;
2852
Sebastian Jansson84848f22018-11-16 10:40:36 +01002853 channel_.reset(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07002854 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002855 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08002856
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002857 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002858
2859 FakeVideoSendStream* stream = AddSendStream();
2860 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
2861
nisse0db023a2016-03-01 04:29:59 -08002862 media_config.video.suspend_below_min_bitrate = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01002863 channel_.reset(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07002864 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002865 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08002866
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002867 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002868
nisse0db023a2016-03-01 04:29:59 -08002869 stream = AddSendStream();
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002870 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
2871}
2872
eladalonf1841382017-06-12 01:16:46 -07002873TEST_F(WebRtcVideoChannelTest, Vp8DenoisingEnabledByDefault) {
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002874 FakeVideoSendStream* stream = AddSendStream();
2875 webrtc::VideoCodecVP8 vp8_settings;
2876 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2877 EXPECT_TRUE(vp8_settings.denoisingOn);
2878}
2879
eladalonf1841382017-06-12 01:16:46 -07002880TEST_F(WebRtcVideoChannelTest, VerifyVp8SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002881 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002882 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002883 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002884
Peter Boström2feafdb2015-09-09 14:32:14 +02002885 // Single-stream settings should apply with RTX as well (verifies that we
2886 // check number of regular SSRCs and not StreamParams::ssrcs which contains
2887 // both RTX and regular SSRCs).
2888 FakeVideoSendStream* stream = SetUpSimulcast(false, true);
Erik Språng143cec12015-04-28 10:01:41 +02002889
Niels Möller805a27e2019-01-21 12:21:27 +01002890 webrtc::test::FrameForwarder frame_forwarder;
2891 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02002892 channel_->SetSend(true);
2893
Niels Möller805a27e2019-01-21 12:21:27 +01002894 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02002895
pbos4cba4eb2015-10-26 11:18:18 -07002896 webrtc::VideoCodecVP8 vp8_settings;
2897 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2898 EXPECT_TRUE(vp8_settings.denoisingOn)
2899 << "VP8 denoising should be on by default.";
2900
Niels Möller805a27e2019-01-21 12:21:27 +01002901 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02002902
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002903 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2904 EXPECT_FALSE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02002905 EXPECT_TRUE(vp8_settings.automaticResizeOn);
2906 EXPECT_TRUE(vp8_settings.frameDroppingOn);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002907
Niels Möller805a27e2019-01-21 12:21:27 +01002908 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002909
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002910 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2911 EXPECT_TRUE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02002912 EXPECT_TRUE(vp8_settings.automaticResizeOn);
2913 EXPECT_TRUE(vp8_settings.frameDroppingOn);
2914
Niels Möllerff40b142018-04-09 08:49:14 +02002915 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boström2feafdb2015-09-09 14:32:14 +02002916 stream = SetUpSimulcast(true, false);
Niels Möller805a27e2019-01-21 12:21:27 +01002917 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02002918 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01002919 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02002920
Mirko Bonadeif859e552018-05-30 15:31:29 +02002921 EXPECT_EQ(3u, stream->GetVideoStreams().size());
Erik Språng143cec12015-04-28 10:01:41 +02002922 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2923 // Autmatic resize off when using simulcast.
2924 EXPECT_FALSE(vp8_settings.automaticResizeOn);
2925 EXPECT_TRUE(vp8_settings.frameDroppingOn);
2926
2927 // In screen-share mode, denoising is forced off and simulcast disabled.
nisse05103312016-03-16 02:22:50 -07002928 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002929 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01002930 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Niels Möller60653ba2016-03-02 11:41:36 +01002931
Niels Möller805a27e2019-01-21 12:21:27 +01002932 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02002933
Mirko Bonadeif859e552018-05-30 15:31:29 +02002934 EXPECT_EQ(1u, stream->GetVideoStreams().size());
Erik Språng143cec12015-04-28 10:01:41 +02002935 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2936 EXPECT_FALSE(vp8_settings.denoisingOn);
2937 // Resizing and frame dropping always off for screen sharing.
2938 EXPECT_FALSE(vp8_settings.automaticResizeOn);
2939 EXPECT_FALSE(vp8_settings.frameDroppingOn);
2940
Niels Möller805a27e2019-01-21 12:21:27 +01002941 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
Erik Språng143cec12015-04-28 10:01:41 +02002942
2943 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2944 EXPECT_FALSE(vp8_settings.denoisingOn);
2945 EXPECT_FALSE(vp8_settings.automaticResizeOn);
2946 EXPECT_FALSE(vp8_settings.frameDroppingOn);
2947
Niels Möllerff40b142018-04-09 08:49:14 +02002948 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Erik Språng143cec12015-04-28 10:01:41 +02002949}
2950
deadbeef119760a2016-04-04 11:43:27 -07002951// Test that setting the same options doesn't result in the encoder being
2952// reconfigured.
eladalonf1841382017-06-12 01:16:46 -07002953TEST_F(WebRtcVideoChannelTest, SetIdenticalOptionsDoesntReconfigureEncoder) {
deadbeef119760a2016-04-04 11:43:27 -07002954 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01002955 webrtc::test::FrameForwarder frame_forwarder;
deadbeef119760a2016-04-04 11:43:27 -07002956
perkjfa10b552016-10-02 23:45:26 -07002957 AddSendStream();
perkjfa10b552016-10-02 23:45:26 -07002958 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002959 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkjfa10b552016-10-02 23:45:26 -07002960 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2961 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
2962
Niels Möller805a27e2019-01-21 12:21:27 +01002963 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
2964 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
2965 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
perkjfa10b552016-10-02 23:45:26 -07002966 // Expect 1 reconfigurations at this point from the initial configuration.
2967 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
deadbeef119760a2016-04-04 11:43:27 -07002968
2969 // Set the options one more time and expect no additional reconfigurations.
Niels Möller805a27e2019-01-21 12:21:27 +01002970 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
perkjfa10b552016-10-02 23:45:26 -07002971 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
2972
2973 // Change |options| and expect 2 reconfigurations.
Oskar Sundbom78807582017-11-16 11:09:55 +01002974 options.video_noise_reduction = true;
Niels Möller805a27e2019-01-21 12:21:27 +01002975 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
deadbeef119760a2016-04-04 11:43:27 -07002976 EXPECT_EQ(2, send_stream->num_encoder_reconfigurations());
2977
Niels Möllerff40b142018-04-09 08:49:14 +02002978 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
deadbeef119760a2016-04-04 11:43:27 -07002979}
2980
eladalonf1841382017-06-12 01:16:46 -07002981class Vp9SettingsTest : public WebRtcVideoChannelTest {
Erik Språng143cec12015-04-28 10:01:41 +02002982 public:
asaperssonc5dabdd2016-03-21 04:15:50 -07002983 Vp9SettingsTest() : Vp9SettingsTest("") {}
2984 explicit Vp9SettingsTest(const char* field_trials)
eladalonf1841382017-06-12 01:16:46 -07002985 : WebRtcVideoChannelTest(field_trials) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +02002986 encoder_factory_->AddSupportedVideoCodecType("VP9");
Erik Språng143cec12015-04-28 10:01:41 +02002987 }
2988 virtual ~Vp9SettingsTest() {}
2989
2990 protected:
Erik Språng143cec12015-04-28 10:01:41 +02002991 void TearDown() override {
2992 // Remove references to encoder_factory_ since this will be destroyed
2993 // before channel_ and engine_.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002994 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
Erik Språng143cec12015-04-28 10:01:41 +02002995 }
Erik Språng143cec12015-04-28 10:01:41 +02002996};
2997
2998TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002999 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003000 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003001 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Erik Språng143cec12015-04-28 10:01:41 +02003002
Peter Boström2feafdb2015-09-09 14:32:14 +02003003 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
Erik Språng143cec12015-04-28 10:01:41 +02003004
Niels Möller805a27e2019-01-21 12:21:27 +01003005 webrtc::test::FrameForwarder frame_forwarder;
3006 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02003007 channel_->SetSend(true);
3008
Niels Möller805a27e2019-01-21 12:21:27 +01003009 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02003010
pbos4cba4eb2015-10-26 11:18:18 -07003011 webrtc::VideoCodecVP9 vp9_settings;
3012 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
jianja5e8aa62017-03-27 10:09:00 -07003013 EXPECT_TRUE(vp9_settings.denoisingOn)
3014 << "VP9 denoising should be on by default.";
pbos4cba4eb2015-10-26 11:18:18 -07003015
Niels Möller805a27e2019-01-21 12:21:27 +01003016 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003017
Erik Språng143cec12015-04-28 10:01:41 +02003018 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3019 EXPECT_FALSE(vp9_settings.denoisingOn);
3020 // Frame dropping always on for real time video.
3021 EXPECT_TRUE(vp9_settings.frameDroppingOn);
3022
Niels Möller805a27e2019-01-21 12:21:27 +01003023 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
Erik Språng143cec12015-04-28 10:01:41 +02003024
3025 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3026 EXPECT_TRUE(vp9_settings.denoisingOn);
3027 EXPECT_TRUE(vp9_settings.frameDroppingOn);
3028
3029 // In screen-share mode, denoising is forced off.
nisse05103312016-03-16 02:22:50 -07003030 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003031 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003032 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
perkj2d5f0912016-02-29 00:04:41 -08003033
Niels Möller805a27e2019-01-21 12:21:27 +01003034 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003035
3036 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3037 EXPECT_FALSE(vp9_settings.denoisingOn);
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003038 // Frame dropping always on for screen sharing.
3039 EXPECT_TRUE(vp9_settings.frameDroppingOn);
Erik Språng143cec12015-04-28 10:01:41 +02003040
Niels Möller805a27e2019-01-21 12:21:27 +01003041 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003042
3043 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3044 EXPECT_FALSE(vp9_settings.denoisingOn);
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003045 EXPECT_TRUE(vp9_settings.frameDroppingOn);
Erik Språng143cec12015-04-28 10:01:41 +02003046
Niels Möllerff40b142018-04-09 08:49:14 +02003047 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003048}
3049
Sergey Silkinf18072e2018-03-14 10:35:35 +01003050TEST_F(Vp9SettingsTest, MultipleSsrcsEnablesSvc) {
3051 cricket::VideoSendParameters parameters;
3052 parameters.codecs.push_back(GetEngineCodec("VP9"));
3053 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3054
3055 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3056
3057 FakeVideoSendStream* stream =
3058 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3059
3060 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3061 EXPECT_EQ(ssrcs.size(), config.rtp.ssrcs.size());
3062
Niels Möller805a27e2019-01-21 12:21:27 +01003063 webrtc::test::FrameForwarder frame_forwarder;
3064 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
Sergey Silkinf18072e2018-03-14 10:35:35 +01003065 channel_->SetSend(true);
3066
Niels Möller805a27e2019-01-21 12:21:27 +01003067 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Sergey Silkinf18072e2018-03-14 10:35:35 +01003068
3069 webrtc::VideoCodecVP9 vp9_settings;
3070 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3071
3072 const size_t kNumSpatialLayers = ssrcs.size();
3073 const size_t kNumTemporalLayers = 3;
3074 EXPECT_EQ(vp9_settings.numberOfSpatialLayers, kNumSpatialLayers);
3075 EXPECT_EQ(vp9_settings.numberOfTemporalLayers, kNumTemporalLayers);
3076
Niels Möllerff40b142018-04-09 08:49:14 +02003077 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr));
Sergey Silkinf18072e2018-03-14 10:35:35 +01003078}
3079
Sergey Silkin8b9b5f92018-12-10 09:28:53 +01003080TEST_F(Vp9SettingsTest, AllEncodingParametersCopied) {
3081 cricket::VideoSendParameters send_parameters;
3082 send_parameters.codecs.push_back(GetEngineCodec("VP9"));
3083 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
3084
3085 const size_t kNumSpatialLayers = 3;
3086 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3087
3088 FakeVideoSendStream* stream =
3089 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3090
3091 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrcs[0]);
3092 ASSERT_EQ(kNumSpatialLayers, parameters.encodings.size());
3093 ASSERT_TRUE(parameters.encodings[0].active);
3094 ASSERT_TRUE(parameters.encodings[1].active);
3095 ASSERT_TRUE(parameters.encodings[2].active);
3096 // Invert value to verify copying.
3097 parameters.encodings[1].active = false;
3098 EXPECT_TRUE(channel_->SetRtpSendParameters(ssrcs[0], parameters).ok());
3099
3100 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
3101
3102 // number_of_streams should be 1 since all spatial layers are sent on the
3103 // same SSRC. But encoding parameters of all layers is supposed to be copied
3104 // and stored in simulcast_layers[].
3105 EXPECT_EQ(1u, encoder_config.number_of_streams);
3106 EXPECT_EQ(encoder_config.simulcast_layers.size(), kNumSpatialLayers);
3107 EXPECT_TRUE(encoder_config.simulcast_layers[0].active);
3108 EXPECT_FALSE(encoder_config.simulcast_layers[1].active);
3109 EXPECT_TRUE(encoder_config.simulcast_layers[2].active);
3110}
3111
asaperssonc5dabdd2016-03-21 04:15:50 -07003112class Vp9SettingsTestWithFieldTrial : public Vp9SettingsTest {
3113 public:
brandtr468da7c2016-11-22 02:16:47 -08003114 explicit Vp9SettingsTestWithFieldTrial(const char* field_trials)
asaperssonc5dabdd2016-03-21 04:15:50 -07003115 : Vp9SettingsTest(field_trials) {}
3116
3117 protected:
3118 void VerifySettings(int num_spatial_layers, int num_temporal_layers) {
3119 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003120 parameters.codecs.push_back(GetEngineCodec("VP9"));
asaperssonc5dabdd2016-03-21 04:15:50 -07003121 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3122
3123 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
3124
Niels Möller805a27e2019-01-21 12:21:27 +01003125 webrtc::test::FrameForwarder frame_forwarder;
3126 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
asaperssonc5dabdd2016-03-21 04:15:50 -07003127 channel_->SetSend(true);
3128
Niels Möller805a27e2019-01-21 12:21:27 +01003129 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
asaperssonc5dabdd2016-03-21 04:15:50 -07003130
3131 webrtc::VideoCodecVP9 vp9_settings;
3132 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3133 EXPECT_EQ(num_spatial_layers, vp9_settings.numberOfSpatialLayers);
3134 EXPECT_EQ(num_temporal_layers, vp9_settings.numberOfTemporalLayers);
3135
Niels Möllerff40b142018-04-09 08:49:14 +02003136 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
asaperssonc5dabdd2016-03-21 04:15:50 -07003137 }
3138};
3139
3140class Vp9SettingsTestWithNoFlag : public Vp9SettingsTestWithFieldTrial {
3141 public:
3142 Vp9SettingsTestWithNoFlag() : Vp9SettingsTestWithFieldTrial("") {}
3143};
3144
3145TEST_F(Vp9SettingsTestWithNoFlag, VerifySettings) {
3146 const int kNumSpatialLayers = 1;
3147 const int kNumTemporalLayers = 1;
3148 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
3149}
3150
3151class Vp9SettingsTestWithInvalidFlag : public Vp9SettingsTestWithFieldTrial {
3152 public:
3153 Vp9SettingsTestWithInvalidFlag()
3154 : Vp9SettingsTestWithFieldTrial("WebRTC-SupportVP9SVC/Default/") {}
3155};
3156
3157TEST_F(Vp9SettingsTestWithInvalidFlag, VerifySettings) {
3158 const int kNumSpatialLayers = 1;
3159 const int kNumTemporalLayers = 1;
3160 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
3161}
3162
3163class Vp9SettingsTestWith2SL3TLFlag : public Vp9SettingsTestWithFieldTrial {
3164 public:
3165 Vp9SettingsTestWith2SL3TLFlag()
3166 : Vp9SettingsTestWithFieldTrial(
3167 "WebRTC-SupportVP9SVC/EnabledByFlag_2SL3TL/") {}
3168};
3169
3170TEST_F(Vp9SettingsTestWith2SL3TLFlag, VerifySettings) {
3171 const int kNumSpatialLayers = 2;
3172 const int kNumTemporalLayers = 3;
3173 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
3174}
3175
Åsa Persson45bbc8a2017-11-13 10:16:47 +01003176TEST_F(WebRtcVideoChannelTest, VerifyMinBitrate) {
3177 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3178 ASSERT_EQ(1u, streams.size());
3179 EXPECT_EQ(cricket::kMinVideoBitrateBps, streams[0].min_bitrate_bps);
3180}
3181
3182TEST_F(WebRtcVideoChannelTest, VerifyMinBitrateWithForcedFallbackFieldTrial) {
3183 webrtc::test::ScopedFieldTrials override_field_trials_(
3184 "WebRTC-VP8-Forced-Fallback-Encoder-v2/Enabled-1,2,34567/");
3185 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3186 ASSERT_EQ(1u, streams.size());
3187 EXPECT_EQ(34567, streams[0].min_bitrate_bps);
3188}
3189
asapersson3c81a1a2017-06-14 05:52:21 -07003190TEST_F(WebRtcVideoChannelTest,
3191 BalancedDegradationPreferenceNotSupportedWithoutFieldtrial) {
3192 webrtc::test::ScopedFieldTrials override_field_trials_(
3193 "WebRTC-Video-BalancedDegradation/Disabled/");
3194 const bool kResolutionScalingEnabled = true;
3195 const bool kFpsScalingEnabled = false;
3196 TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
3197}
3198
3199TEST_F(WebRtcVideoChannelTest,
3200 BalancedDegradationPreferenceSupportedBehindFieldtrial) {
3201 webrtc::test::ScopedFieldTrials override_field_trials_(
3202 "WebRTC-Video-BalancedDegradation/Enabled/");
3203 const bool kResolutionScalingEnabled = true;
3204 const bool kFpsScalingEnabled = true;
3205 TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
3206}
3207
eladalonf1841382017-06-12 01:16:46 -07003208TEST_F(WebRtcVideoChannelTest, AdaptsOnOveruse) {
Erik Språngefbde372015-04-29 16:21:28 +02003209 TestCpuAdaptation(true, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003210}
3211
eladalonf1841382017-06-12 01:16:46 -07003212TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenDisabled) {
Erik Språngefbde372015-04-29 16:21:28 +02003213 TestCpuAdaptation(false, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003214}
3215
Niels Möller3de32e62019-01-18 08:42:18 +01003216TEST_F(WebRtcVideoChannelTest, DoesNotAdaptWhenScreeensharing) {
3217 TestCpuAdaptation(false, true);
3218}
3219
eladalonf1841382017-06-12 01:16:46 -07003220TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenScreensharing) {
Erik Språngefbde372015-04-29 16:21:28 +02003221 TestCpuAdaptation(true, true);
3222}
3223
eladalonf1841382017-06-12 01:16:46 -07003224TEST_F(WebRtcVideoChannelTest, PreviousAdaptationDoesNotApplyToScreenshare) {
magjed509e4fe2016-11-18 01:34:11 -08003225 cricket::VideoCodec codec = GetEngineCodec("VP8");
Per766ad3b2016-04-05 15:23:49 +02003226 cricket::VideoSendParameters parameters;
3227 parameters.codecs.push_back(codec);
3228
kthelgason2bc68642017-02-07 07:02:22 -08003229 MediaConfig media_config = GetMediaConfig();
Niels Möller1d7ecd22018-01-18 15:25:12 +01003230 media_config.video.enable_cpu_adaptation = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003231 channel_.reset(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003232 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08003233 channel_->OnReadyToSend(true);
Per766ad3b2016-04-05 15:23:49 +02003234 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3235
3236 AddSendStream();
Niels Möller805a27e2019-01-21 12:21:27 +01003237 webrtc::test::FrameForwarder frame_forwarder;
Per766ad3b2016-04-05 15:23:49 +02003238
Per766ad3b2016-04-05 15:23:49 +02003239 ASSERT_TRUE(channel_->SetSend(true));
3240 cricket::VideoOptions camera_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003241 camera_options.is_screencast = false;
Niels Möller805a27e2019-01-21 12:21:27 +01003242 channel_->SetVideoSend(last_ssrc_, &camera_options, &frame_forwarder);
Per766ad3b2016-04-05 15:23:49 +02003243
3244 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
3245 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
Per766ad3b2016-04-05 15:23:49 +02003246
Niels Möllerdcc70292019-01-15 16:32:38 +01003247 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
3248 // Dont' expect anything on framerate_scaling_enabled, since the default is
3249 // transitioning from MAINTAIN_FRAMERATE to BALANCED.
Per766ad3b2016-04-05 15:23:49 +02003250
Niels Möllerdcc70292019-01-15 16:32:38 +01003251 // Switch to screen share. Expect no resolution scaling.
Per766ad3b2016-04-05 15:23:49 +02003252 cricket::VideoOptions screenshare_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003253 screenshare_options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003254 channel_->SetVideoSend(last_ssrc_, &screenshare_options, &frame_forwarder);
sprangf24a0642017-02-28 13:23:26 -08003255 ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
3256 send_stream = fake_call_->GetVideoSendStreams().front();
Niels Möllerdcc70292019-01-15 16:32:38 +01003257 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
Per766ad3b2016-04-05 15:23:49 +02003258
Niels Möllerdcc70292019-01-15 16:32:38 +01003259 // Switch back to the normal capturer. Expect resolution scaling to be
3260 // reenabled.
Niels Möller805a27e2019-01-21 12:21:27 +01003261 channel_->SetVideoSend(last_ssrc_, &camera_options, &frame_forwarder);
3262 send_stream = fake_call_->GetVideoSendStreams().front();
sprangf24a0642017-02-28 13:23:26 -08003263 ASSERT_EQ(3, fake_call_->GetNumCreatedSendStreams());
3264 send_stream = fake_call_->GetVideoSendStreams().front();
Niels Möllerdcc70292019-01-15 16:32:38 +01003265 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
Per766ad3b2016-04-05 15:23:49 +02003266
Niels Möllerff40b142018-04-09 08:49:14 +02003267 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Per766ad3b2016-04-05 15:23:49 +02003268}
3269
asapersson3c81a1a2017-06-14 05:52:21 -07003270// TODO(asapersson): Remove this test when the balanced field trial is removed.
3271void WebRtcVideoChannelTest::TestDegradationPreference(
3272 bool resolution_scaling_enabled,
3273 bool fps_scaling_enabled) {
3274 cricket::VideoCodec codec = GetEngineCodec("VP8");
3275 cricket::VideoSendParameters parameters;
3276 parameters.codecs.push_back(codec);
3277
3278 MediaConfig media_config = GetMediaConfig();
Niels Möller1d7ecd22018-01-18 15:25:12 +01003279 media_config.video.enable_cpu_adaptation = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003280 channel_.reset(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003281 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions()));
asapersson3c81a1a2017-06-14 05:52:21 -07003282 channel_->OnReadyToSend(true);
3283
3284 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3285
3286 AddSendStream();
3287
Niels Möller805a27e2019-01-21 12:21:27 +01003288 webrtc::test::FrameForwarder frame_forwarder;
asapersson3c81a1a2017-06-14 05:52:21 -07003289 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01003290 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
asapersson3c81a1a2017-06-14 05:52:21 -07003291
3292 EXPECT_TRUE(channel_->SetSend(true));
3293
3294 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3295 EXPECT_EQ(resolution_scaling_enabled,
3296 send_stream->resolution_scaling_enabled());
3297 EXPECT_EQ(fps_scaling_enabled, send_stream->framerate_scaling_enabled());
3298
Niels Möllerff40b142018-04-09 08:49:14 +02003299 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
asapersson3c81a1a2017-06-14 05:52:21 -07003300}
3301
eladalonf1841382017-06-12 01:16:46 -07003302void WebRtcVideoChannelTest::TestCpuAdaptation(bool enable_overuse,
3303 bool is_screenshare) {
magjed509e4fe2016-11-18 01:34:11 -08003304 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003305 cricket::VideoSendParameters parameters;
3306 parameters.codecs.push_back(codec);
nisse51542be2016-02-12 02:27:06 -08003307
kthelgason2bc68642017-02-07 07:02:22 -08003308 MediaConfig media_config = GetMediaConfig();
3309 if (enable_overuse) {
Niels Möller1d7ecd22018-01-18 15:25:12 +01003310 media_config.video.enable_cpu_adaptation = true;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003311 }
Sebastian Jansson84848f22018-11-16 10:40:36 +01003312 channel_.reset(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003313 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08003314 channel_->OnReadyToSend(true);
nisse51542be2016-02-12 02:27:06 -08003315
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003316 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003317
3318 AddSendStream();
3319
Niels Möller805a27e2019-01-21 12:21:27 +01003320 webrtc::test::FrameForwarder frame_forwarder;
nisse05103312016-03-16 02:22:50 -07003321 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003322 options.is_screencast = is_screenshare;
Niels Möller805a27e2019-01-21 12:21:27 +01003323 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003324
3325 EXPECT_TRUE(channel_->SetSend(true));
3326
solenberge5269742015-09-08 05:13:22 -07003327 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
perkj2d5f0912016-02-29 00:04:41 -08003328
sprangc5d62e22017-04-02 23:53:04 -07003329 if (!enable_overuse) {
perkj803d97f2016-11-01 11:45:46 -07003330 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
sprangc5d62e22017-04-02 23:53:04 -07003331 EXPECT_FALSE(send_stream->framerate_scaling_enabled());
Niels Möller805a27e2019-01-21 12:21:27 +01003332 } else if (is_screenshare) {
sprangc5d62e22017-04-02 23:53:04 -07003333 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
3334 EXPECT_TRUE(send_stream->framerate_scaling_enabled());
3335 } else {
3336 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
3337 EXPECT_FALSE(send_stream->framerate_scaling_enabled());
3338 }
Niels Möllerff40b142018-04-09 08:49:14 +02003339 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003340}
3341
eladalonf1841382017-06-12 01:16:46 -07003342TEST_F(WebRtcVideoChannelTest, EstimatesNtpStartTimeCorrectly) {
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003343 // Start at last timestamp to verify that wraparounds are estimated correctly.
3344 static const uint32_t kInitialTimestamp = 0xFFFFFFFFu;
3345 static const int64_t kInitialNtpTimeMs = 1247891230;
3346 static const int kFrameOffsetMs = 20;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003347 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003348
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003349 FakeVideoReceiveStream* stream = AddRecvStream();
3350 cricket::FakeVideoRenderer renderer;
nisse08582ff2016-02-04 01:24:52 -08003351 EXPECT_TRUE(channel_->SetSink(last_ssrc_, &renderer));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003352
Artem Titov1ebfb6a2019-01-03 23:49:37 +01003353 webrtc::VideoFrame video_frame =
3354 webrtc::VideoFrame::Builder()
3355 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
3356 .set_timestamp_rtp(kInitialTimestamp)
3357 .set_timestamp_us(0)
3358 .set_rotation(webrtc::kVideoRotation_0)
3359 .build();
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003360 // Initial NTP time is not available on the first frame, but should still be
3361 // able to be estimated.
nisseeb83a1a2016-03-21 01:27:56 -07003362 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003363
3364 EXPECT_EQ(1, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003365
3366 // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which
3367 // triggers a constant-overflow warning, hence we're calculating it explicitly
3368 // here.
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +02003369 fake_clock_.AdvanceTimeMicros(kFrameOffsetMs * rtc::kNumMicrosecsPerMillisec);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003370 video_frame.set_timestamp(kFrameOffsetMs * 90 - 1);
3371 video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs);
nisseeb83a1a2016-03-21 01:27:56 -07003372 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003373
3374 EXPECT_EQ(2, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003375
3376 // Verify that NTP time has been correctly deduced.
3377 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003378 ASSERT_TRUE(channel_->GetStats(&info));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003379 ASSERT_EQ(1u, info.receivers.size());
3380 EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003381}
3382
eladalonf1841382017-06-12 01:16:46 -07003383TEST_F(WebRtcVideoChannelTest, SetDefaultSendCodecs) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02003384 AssignDefaultAptRtxTypes();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003385 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003386
3387 VideoCodec codec;
3388 EXPECT_TRUE(channel_->GetSendCodec(&codec));
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00003389 EXPECT_TRUE(codec.Matches(engine_.codecs()[0]));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003390
3391 // Using a RTX setup to verify that the default RTX payload type is good.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003392 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3393 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003394 FakeVideoSendStream* stream = AddSendStream(
3395 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
perkj26091b12016-09-01 01:17:40 -07003396 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003397
3398 // Make sure NACK and FEC are enabled on the correct payload types.
3399 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
magjed509e4fe2016-11-18 01:34:11 -08003400 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
3401 EXPECT_EQ(GetEngineCodec("red").id, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003402
3403 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
3404 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
Shao Changbine62202f2015-04-21 20:24:50 +08003405 VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003406 // TODO(juberti): Check RTCP, PLI, TMMBR.
3407}
3408
brandtr31bd2242017-05-19 05:47:46 -07003409// The following four tests ensures that FlexFEC is not activated by default
3410// when the field trials are not enabled.
3411// TODO(brandtr): Remove or update these tests when FlexFEC _is_ enabled by
3412// default.
Yves Gerey665174f2018-06-19 15:03:05 +02003413TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithoutSsrcNotExposedByDefault) {
brandtr468da7c2016-11-22 02:16:47 -08003414 FakeVideoSendStream* stream = AddSendStream();
3415 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3416
brandtr3d200bd2017-01-16 06:59:19 -08003417 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr31bd2242017-05-19 05:47:46 -07003418 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3419 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
brandtr468da7c2016-11-22 02:16:47 -08003420}
3421
eladalonf1841382017-06-12 01:16:46 -07003422TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithSsrcNotExposedByDefault) {
brandtr468da7c2016-11-22 02:16:47 -08003423 FakeVideoSendStream* stream = AddSendStream(
3424 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3425 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3426
brandtr3d200bd2017-01-16 06:59:19 -08003427 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr31bd2242017-05-19 05:47:46 -07003428 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3429 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3430}
3431
Yves Gerey665174f2018-06-19 15:03:05 +02003432TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithoutSsrcNotExposedByDefault) {
brandtr31bd2242017-05-19 05:47:46 -07003433 AddRecvStream();
3434
3435 const std::vector<FakeFlexfecReceiveStream*>& streams =
3436 fake_call_->GetFlexfecReceiveStreams();
3437 EXPECT_TRUE(streams.empty());
3438}
3439
eladalonf1841382017-06-12 01:16:46 -07003440TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithSsrcNotExposedByDefault) {
brandtr31bd2242017-05-19 05:47:46 -07003441 AddRecvStream(
3442 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3443
3444 const std::vector<FakeFlexfecReceiveStream*>& streams =
3445 fake_call_->GetFlexfecReceiveStreams();
3446 EXPECT_TRUE(streams.empty());
brandtr468da7c2016-11-22 02:16:47 -08003447}
3448
3449// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
3450// tests that use this test fixture into the corresponding "non-field trial"
3451// tests.
eladalonf1841382017-06-12 01:16:46 -07003452class WebRtcVideoChannelFlexfecRecvTest : public WebRtcVideoChannelTest {
brandtr468da7c2016-11-22 02:16:47 -08003453 public:
eladalonf1841382017-06-12 01:16:46 -07003454 WebRtcVideoChannelFlexfecRecvTest()
3455 : WebRtcVideoChannelTest("WebRTC-FlexFEC-03-Advertised/Enabled/") {}
brandtr468da7c2016-11-22 02:16:47 -08003456};
3457
eladalonf1841382017-06-12 01:16:46 -07003458TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr36e7d702017-01-13 07:15:54 -08003459 DefaultFlexfecCodecHasTransportCcAndRembFeedbackParam) {
3460 EXPECT_TRUE(cricket::HasTransportCc(GetEngineCodec("flexfec-03")));
3461 EXPECT_TRUE(cricket::HasRemb(GetEngineCodec("flexfec-03")));
3462}
3463
eladalonf1841382017-06-12 01:16:46 -07003464TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithoutSsrc) {
brandtr31bd2242017-05-19 05:47:46 -07003465 AddRecvStream();
3466
3467 const std::vector<FakeFlexfecReceiveStream*>& streams =
3468 fake_call_->GetFlexfecReceiveStreams();
3469 EXPECT_TRUE(streams.empty());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003470
3471 const std::vector<FakeVideoReceiveStream*>& video_streams =
3472 fake_call_->GetVideoReceiveStreams();
3473 ASSERT_EQ(1U, video_streams.size());
3474 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3475 EXPECT_EQ(0, video_stream.GetNumAddedSecondarySinks());
3476 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr31bd2242017-05-19 05:47:46 -07003477}
3478
eladalonf1841382017-06-12 01:16:46 -07003479TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithSsrc) {
brandtr31bd2242017-05-19 05:47:46 -07003480 AddRecvStream(
3481 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3482
3483 const std::vector<FakeFlexfecReceiveStream*>& streams =
3484 fake_call_->GetFlexfecReceiveStreams();
3485 ASSERT_EQ(1U, streams.size());
3486 const FakeFlexfecReceiveStream* stream = streams.front();
3487 const webrtc::FlexfecReceiveStream::Config& config = stream->GetConfig();
3488 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.payload_type);
3489 EXPECT_EQ(kFlexfecSsrc, config.remote_ssrc);
3490 ASSERT_EQ(1U, config.protected_media_ssrcs.size());
3491 EXPECT_EQ(kSsrcs1[0], config.protected_media_ssrcs[0]);
brandtr7cd28b92017-09-22 00:26:25 -07003492
3493 const std::vector<FakeVideoReceiveStream*>& video_streams =
3494 fake_call_->GetVideoReceiveStreams();
3495 ASSERT_EQ(1U, video_streams.size());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003496 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3497 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
brandtr7cd28b92017-09-22 00:26:25 -07003498 const webrtc::VideoReceiveStream::Config& video_config =
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003499 video_stream.GetConfig();
brandtr7cd28b92017-09-22 00:26:25 -07003500 EXPECT_TRUE(video_config.rtp.protected_by_flexfec);
brandtr31bd2242017-05-19 05:47:46 -07003501}
3502
eladalonf1841382017-06-12 01:16:46 -07003503TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr11fb4722017-05-30 01:31:37 -07003504 EnablingFlexfecDoesNotRecreateVideoReceiveStream) {
3505 cricket::VideoRecvParameters recv_parameters;
3506 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3507 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3508
3509 AddRecvStream(
3510 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3511 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003512 const std::vector<FakeVideoReceiveStream*>& video_streams =
3513 fake_call_->GetVideoReceiveStreams();
3514 ASSERT_EQ(1U, video_streams.size());
3515 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3516 EXPECT_EQ(0, video_stream.GetNumAddedSecondarySinks());
3517 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003518
3519 // Enable FlexFEC.
3520 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3521 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3522 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams())
3523 << "Enabling FlexFEC should create FlexfecReceiveStream.";
3524 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
3525 << "Enabling FlexFEC should not create VideoReceiveStream.";
3526 EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size())
3527 << "Enabling FlexFEC should create a single FlexfecReceiveStream.";
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003528 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
3529 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003530}
3531
eladalonf1841382017-06-12 01:16:46 -07003532TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr11fb4722017-05-30 01:31:37 -07003533 DisablingFlexfecDoesNotRecreateVideoReceiveStream) {
3534 cricket::VideoRecvParameters recv_parameters;
3535 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3536 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3537 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3538
3539 AddRecvStream(
3540 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3541 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
brandtr11fb4722017-05-30 01:31:37 -07003542 EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003543 const std::vector<FakeVideoReceiveStream*>& video_streams =
3544 fake_call_->GetVideoReceiveStreams();
3545 ASSERT_EQ(1U, video_streams.size());
3546 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3547 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
3548 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003549
3550 // Disable FlexFEC.
3551 recv_parameters.codecs.clear();
3552 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3553 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3554 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams())
3555 << "Disabling FlexFEC should not recreate VideoReceiveStream.";
3556 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
3557 << "Disabling FlexFEC should not destroy VideoReceiveStream.";
3558 EXPECT_TRUE(fake_call_->GetFlexfecReceiveStreams().empty())
3559 << "Disabling FlexFEC should destroy FlexfecReceiveStream.";
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003560 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
3561 EXPECT_EQ(1, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003562}
3563
brandtr31bd2242017-05-19 05:47:46 -07003564// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
3565// tests that use this test fixture into the corresponding "non-field trial"
3566// tests.
eladalonf1841382017-06-12 01:16:46 -07003567class WebRtcVideoChannelFlexfecSendRecvTest : public WebRtcVideoChannelTest {
brandtr31bd2242017-05-19 05:47:46 -07003568 public:
eladalonf1841382017-06-12 01:16:46 -07003569 WebRtcVideoChannelFlexfecSendRecvTest()
3570 : WebRtcVideoChannelTest(
brandtr31bd2242017-05-19 05:47:46 -07003571 "WebRTC-FlexFEC-03-Advertised/Enabled/WebRTC-FlexFEC-03/Enabled/") {
3572 }
3573};
3574
Yves Gerey665174f2018-06-19 15:03:05 +02003575TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithoutSsrc) {
brandtr468da7c2016-11-22 02:16:47 -08003576 FakeVideoSendStream* stream = AddSendStream();
3577 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3578
brandtr3d200bd2017-01-16 06:59:19 -08003579 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
3580 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3581 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
brandtr468da7c2016-11-22 02:16:47 -08003582}
3583
eladalonf1841382017-06-12 01:16:46 -07003584TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithSsrc) {
brandtr468da7c2016-11-22 02:16:47 -08003585 FakeVideoSendStream* stream = AddSendStream(
3586 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3587 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3588
brandtr3d200bd2017-01-16 06:59:19 -08003589 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
3590 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
3591 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
3592 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08003593}
3594
eladalonf1841382017-06-12 01:16:46 -07003595TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003596 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003597 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003598 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003599
3600 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07003601 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003602
brandtrb5f2c3f2016-10-04 23:28:39 -07003603 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type);
3604 EXPECT_EQ(-1, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003605}
3606
eladalonf1841382017-06-12 01:16:46 -07003607TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetSendCodecsWithoutFec) {
brandtr468da7c2016-11-22 02:16:47 -08003608 cricket::VideoSendParameters parameters;
3609 parameters.codecs.push_back(GetEngineCodec("VP8"));
3610 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3611
3612 FakeVideoSendStream* stream = AddSendStream();
3613 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3614
brandtr3d200bd2017-01-16 06:59:19 -08003615 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr468da7c2016-11-22 02:16:47 -08003616}
3617
eladalonf1841382017-06-12 01:16:46 -07003618TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvCodecsWithFec) {
brandtr9c3d4c42017-01-23 06:59:13 -08003619 AddRecvStream(
3620 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08003621
3622 cricket::VideoRecvParameters recv_parameters;
3623 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3624 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3625 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
brandtr9d58d942017-02-03 04:43:41 -08003626
3627 const std::vector<FakeFlexfecReceiveStream*>& flexfec_streams =
3628 fake_call_->GetFlexfecReceiveStreams();
3629 ASSERT_EQ(1U, flexfec_streams.size());
3630 const FakeFlexfecReceiveStream* flexfec_stream = flexfec_streams.front();
3631 const webrtc::FlexfecReceiveStream::Config& flexfec_stream_config =
3632 flexfec_stream->GetConfig();
brandtr9c3d4c42017-01-23 06:59:13 -08003633 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9d58d942017-02-03 04:43:41 -08003634 flexfec_stream_config.payload_type);
3635 EXPECT_EQ(kFlexfecSsrc, flexfec_stream_config.remote_ssrc);
3636 ASSERT_EQ(1U, flexfec_stream_config.protected_media_ssrcs.size());
3637 EXPECT_EQ(kSsrcs1[0], flexfec_stream_config.protected_media_ssrcs[0]);
3638 const std::vector<FakeVideoReceiveStream*>& video_streams =
3639 fake_call_->GetVideoReceiveStreams();
3640 const FakeVideoReceiveStream* video_stream = video_streams.front();
3641 const webrtc::VideoReceiveStream::Config& video_stream_config =
3642 video_stream->GetConfig();
3643 EXPECT_EQ(video_stream_config.rtp.local_ssrc,
3644 flexfec_stream_config.local_ssrc);
3645 EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
3646 EXPECT_EQ(video_stream_config.rtcp_send_transport,
3647 flexfec_stream_config.rtcp_send_transport);
3648 // TODO(brandtr): Update this EXPECT when we set |transport_cc| in a
3649 // spec-compliant way.
3650 EXPECT_EQ(video_stream_config.rtp.transport_cc,
3651 flexfec_stream_config.transport_cc);
3652 EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
3653 EXPECT_EQ(video_stream_config.rtp.extensions,
3654 flexfec_stream_config.rtp_header_extensions);
brandtr9c3d4c42017-01-23 06:59:13 -08003655}
3656
brandtr31bd2242017-05-19 05:47:46 -07003657// We should not send FlexFEC, even if we advertise it, unless the right
3658// field trial is set.
3659// TODO(brandtr): Remove when FlexFEC is enabled by default.
eladalonf1841382017-06-12 01:16:46 -07003660TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07003661 SetSendCodecsWithoutSsrcWithFecDoesNotEnableFec) {
3662 cricket::VideoSendParameters parameters;
3663 parameters.codecs.push_back(GetEngineCodec("VP8"));
3664 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3665 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3666
3667 FakeVideoSendStream* stream = AddSendStream();
3668 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3669
3670 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003671 EXPECT_EQ(0u, config.rtp.flexfec.ssrc);
brandtr31bd2242017-05-19 05:47:46 -07003672 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3673}
3674
eladalonf1841382017-06-12 01:16:46 -07003675TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07003676 SetSendCodecsWithSsrcWithFecDoesNotEnableFec) {
3677 cricket::VideoSendParameters parameters;
3678 parameters.codecs.push_back(GetEngineCodec("VP8"));
3679 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3680 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3681
3682 FakeVideoSendStream* stream = AddSendStream(
3683 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3684 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3685
3686 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003687 EXPECT_EQ(0u, config.rtp.flexfec.ssrc);
brandtr31bd2242017-05-19 05:47:46 -07003688 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3689}
3690
eladalonf1841382017-06-12 01:16:46 -07003691TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003692 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
magjed509e4fe2016-11-18 01:34:11 -08003693 const int kUnusedPayloadType = 127;
3694 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType));
3695
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003696 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003697 cricket::VideoCodec rtx_codec(kUnusedPayloadType, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003698 parameters.codecs.push_back(rtx_codec);
3699 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003700 << "RTX codec without associated payload type should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003701}
3702
eladalonf1841382017-06-12 01:16:46 -07003703TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003704 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
magjed509e4fe2016-11-18 01:34:11 -08003705 const int kUnusedPayloadType1 = 126;
3706 const int kUnusedPayloadType2 = 127;
3707 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
3708 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
3709 {
3710 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
3711 kUnusedPayloadType1, GetEngineCodec("VP8").id);
3712 cricket::VideoSendParameters parameters;
3713 parameters.codecs.push_back(GetEngineCodec("VP8"));
3714 parameters.codecs.push_back(rtx_codec);
3715 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3716 }
3717 {
3718 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
3719 kUnusedPayloadType1, kUnusedPayloadType2);
3720 cricket::VideoSendParameters parameters;
3721 parameters.codecs.push_back(GetEngineCodec("VP8"));
3722 parameters.codecs.push_back(rtx_codec);
3723 EXPECT_FALSE(channel_->SetSendParameters(parameters))
3724 << "RTX without matching video codec should be rejected.";
3725 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003726}
3727
eladalonf1841382017-06-12 01:16:46 -07003728TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithChangedRtxPayloadType) {
brandtr14742122017-01-27 04:53:07 -08003729 const int kUnusedPayloadType1 = 126;
3730 const int kUnusedPayloadType2 = 127;
3731 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
3732 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
3733
3734 // SSRCs for RTX.
3735 cricket::StreamParams params =
3736 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
3737 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
3738 AddSendStream(params);
3739
3740 // Original payload type for RTX.
3741 cricket::VideoSendParameters parameters;
3742 parameters.codecs.push_back(GetEngineCodec("VP8"));
3743 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
3744 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
3745 parameters.codecs.push_back(rtx_codec);
3746 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3747 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
3748 const webrtc::VideoSendStream::Config& config_before =
3749 fake_call_->GetVideoSendStreams()[0]->GetConfig();
3750 EXPECT_EQ(kUnusedPayloadType1, config_before.rtp.rtx.payload_type);
3751 ASSERT_EQ(1U, config_before.rtp.rtx.ssrcs.size());
3752 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx.ssrcs[0]);
3753
3754 // Change payload type for RTX.
3755 parameters.codecs[1].id = kUnusedPayloadType2;
3756 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3757 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
3758 const webrtc::VideoSendStream::Config& config_after =
3759 fake_call_->GetVideoSendStreams()[0]->GetConfig();
3760 EXPECT_EQ(kUnusedPayloadType2, config_after.rtp.rtx.payload_type);
3761 ASSERT_EQ(1U, config_after.rtp.rtx.ssrcs.size());
3762 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx.ssrcs[0]);
3763}
3764
eladalonf1841382017-06-12 01:16:46 -07003765TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003766 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003767 parameters.codecs.push_back(GetEngineCodec("VP8"));
3768 parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003769 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003770
3771 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07003772 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003773
magjed509e4fe2016-11-18 01:34:11 -08003774 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003775
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003776 parameters.codecs.pop_back();
3777 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003778 stream = fake_call_->GetVideoSendStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08003779 ASSERT_TRUE(stream != nullptr);
perkj26091b12016-09-01 01:17:40 -07003780 config = stream->GetConfig().Copy();
brandtrb5f2c3f2016-10-04 23:28:39 -07003781 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08003782 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
3783}
3784
eladalonf1841382017-06-12 01:16:46 -07003785TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07003786 SetSendCodecsWithoutFecDisablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08003787 cricket::VideoSendParameters parameters;
3788 parameters.codecs.push_back(GetEngineCodec("VP8"));
3789 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3790 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3791
3792 FakeVideoSendStream* stream = AddSendStream(
3793 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3794 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3795
brandtr3d200bd2017-01-16 06:59:19 -08003796 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
3797 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
brandtr468da7c2016-11-22 02:16:47 -08003798 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
3799 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
3800
3801 parameters.codecs.pop_back();
3802 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3803 stream = fake_call_->GetVideoSendStreams()[0];
3804 ASSERT_TRUE(stream != nullptr);
3805 config = stream->GetConfig().Copy();
brandtr3d200bd2017-01-16 06:59:19 -08003806 EXPECT_EQ(-1, config.rtp.flexfec.payload_type)
brandtr468da7c2016-11-22 02:16:47 -08003807 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003808}
3809
eladalonf1841382017-06-12 01:16:46 -07003810TEST_F(WebRtcVideoChannelTest, SetSendCodecsChangesExistingStreams) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003811 cricket::VideoSendParameters parameters;
perkj26752742016-10-24 01:21:16 -07003812 cricket::VideoCodec codec(100, "VP8");
3813 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax);
3814 parameters.codecs.push_back(codec);
perkjfa10b552016-10-02 23:45:26 -07003815
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003816 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003817 channel_->SetSend(true);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00003818
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003819 FakeVideoSendStream* stream = AddSendStream();
Niels Möller805a27e2019-01-21 12:21:27 +01003820 webrtc::test::FrameForwarder frame_forwarder;
3821 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003822
3823 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07003824 EXPECT_EQ(kDefaultQpMax, streams[0].max_qp);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00003825
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003826 parameters.codecs.clear();
perkj26752742016-10-24 01:21:16 -07003827 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax + 1);
3828 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003829 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003830 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07003831 EXPECT_EQ(kDefaultQpMax + 1, streams[0].max_qp);
Niels Möllerff40b142018-04-09 08:49:14 +02003832 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003833}
3834
eladalonf1841382017-06-12 01:16:46 -07003835TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitrates) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00003836 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
3837 200000);
3838}
3839
eladalonf1841382017-06-12 01:16:46 -07003840TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithHighMaxBitrate) {
pbos@webrtc.orga5f6fb52015-03-23 22:29:39 +00003841 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
3842 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3843 ASSERT_EQ(1u, streams.size());
3844 EXPECT_EQ(10000000, streams[0].max_bitrate_bps);
3845}
3846
eladalonf1841382017-06-12 01:16:46 -07003847TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org00873182014-11-25 14:03:34 +00003848 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003849 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
pbos@webrtc.org00873182014-11-25 14:03:34 +00003850}
3851
eladalonf1841382017-06-12 01:16:46 -07003852TEST_F(WebRtcVideoChannelTest, SetSendCodecsCapsMinAndStartBitrate) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00003853 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003854}
3855
eladalonf1841382017-06-12 01:16:46 -07003856TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectsMaxLessThanMinBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003857 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "300";
3858 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "200";
3859 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003860}
3861
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003862// Test that when both the codec-specific bitrate params and max_bandwidth_bps
3863// are present in the same send parameters, the settings are combined correctly.
eladalonf1841382017-06-12 01:16:46 -07003864TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitratesAndMaxSendBandwidth) {
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003865 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
3866 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
3867 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
3868 send_parameters_.max_bandwidth_bps = 400000;
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003869 // We expect max_bandwidth_bps to take priority, if set.
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003870 ExpectSetBitrateParameters(100000, 200000, 400000);
3871 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3872 // Since the codec isn't changing, start_bitrate_bps should be -1.
3873 ExpectSetBitrateParameters(100000, -1, 350000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003874
3875 // Decrease max_bandwidth_bps.
3876 send_parameters_.max_bandwidth_bps = 350000;
3877 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003878
3879 // Now try again with the values flipped around.
3880 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
3881 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003882 ExpectSetBitrateParameters(100000, 200000, 300000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003883 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003884
3885 // If we change the codec max, max_bandwidth_bps should still apply.
3886 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003887 ExpectSetBitrateParameters(100000, 200000, 300000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003888 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003889}
3890
Yves Gerey665174f2018-06-19 15:03:05 +02003891TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldPreserveOtherBitrates) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00003892 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
3893 200000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003894 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003895 // Setting max bitrate should keep previous min bitrate.
3896 // Setting max bitrate should not reset start bitrate.
3897 ExpectSetBitrateParameters(100000, -1, 300000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003898 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org00873182014-11-25 14:03:34 +00003899}
3900
eladalonf1841382017-06-12 01:16:46 -07003901TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldBeRemovable) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003902 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003903 ExpectSetMaxBitrate(300000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003904 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos5c7760a2017-03-10 11:23:12 -08003905 // -1 means to disable max bitrate (set infinite).
3906 send_parameters_.max_bandwidth_bps = -1;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003907 ExpectSetMaxBitrate(-1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003908 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003909}
3910
eladalonf1841382017-06-12 01:16:46 -07003911TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthAndAddSendStream) {
perkjfa10b552016-10-02 23:45:26 -07003912 send_parameters_.max_bandwidth_bps = 99999;
3913 FakeVideoSendStream* stream = AddSendStream();
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003914 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
perkjfa10b552016-10-02 23:45:26 -07003915 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
perkjfa10b552016-10-02 23:45:26 -07003916 ASSERT_EQ(1u, stream->GetVideoStreams().size());
3917 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
3918 stream->GetVideoStreams()[0].max_bitrate_bps);
3919
3920 send_parameters_.max_bandwidth_bps = 77777;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003921 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
perkjfa10b552016-10-02 23:45:26 -07003922 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
3923 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
perkjfa10b552016-10-02 23:45:26 -07003924 stream->GetVideoStreams()[0].max_bitrate_bps);
3925}
3926
Seth Hampsonfeec91e2018-07-13 10:41:10 -07003927// Tests that when the codec specific max bitrate and VideoSendParameters
3928// max_bandwidth_bps are used, that it sets the VideoStream's max bitrate
3929// appropriately.
3930TEST_F(WebRtcVideoChannelTest,
3931 MaxBitratePrioritizesVideoSendParametersOverCodecMaxBitrate) {
3932 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
3933 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
3934 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
3935 send_parameters_.max_bandwidth_bps = -1;
3936 AddSendStream();
3937 ExpectSetMaxBitrate(300000);
3938 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
3939
3940 std::vector<FakeVideoSendStream*> video_send_streams = GetFakeSendStreams();
3941 ASSERT_EQ(1u, video_send_streams.size());
3942 FakeVideoSendStream* video_send_stream = video_send_streams[0];
3943 ASSERT_EQ(1u, video_send_streams[0]->GetVideoStreams().size());
3944 // First the max bitrate is set based upon the codec param.
3945 EXPECT_EQ(300000,
3946 video_send_streams[0]->GetVideoStreams()[0].max_bitrate_bps);
3947
3948 // The VideoSendParameters max bitrate overrides the codec's.
3949 send_parameters_.max_bandwidth_bps = 500000;
3950 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
3951 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
3952 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
3953 EXPECT_EQ(500000, video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
3954}
3955
3956// Tests that when the codec specific max bitrate and RtpParameters
3957// max_bitrate_bps are used, that it sets the VideoStream's max bitrate
3958// appropriately.
3959TEST_F(WebRtcVideoChannelTest,
3960 MaxBitratePrioritizesRtpParametersOverCodecMaxBitrate) {
3961 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
3962 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
3963 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
3964 send_parameters_.max_bandwidth_bps = -1;
3965 AddSendStream();
3966 ExpectSetMaxBitrate(300000);
3967 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
3968
3969 std::vector<FakeVideoSendStream*> video_send_streams = GetFakeSendStreams();
3970 ASSERT_EQ(1u, video_send_streams.size());
3971 FakeVideoSendStream* video_send_stream = video_send_streams[0];
3972 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
3973 // First the max bitrate is set based upon the codec param.
3974 EXPECT_EQ(300000, video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
3975
3976 // The RtpParameter max bitrate overrides the codec's.
3977 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
3978 ASSERT_EQ(1u, parameters.encodings.size());
3979 parameters.encodings[0].max_bitrate_bps = 500000;
3980 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
3981 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
3982 EXPECT_EQ(parameters.encodings[0].max_bitrate_bps,
3983 video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
3984}
3985
Åsa Persson55659812018-06-18 17:51:32 +02003986TEST_F(WebRtcVideoChannelTest,
3987 MaxBitrateIsMinimumOfMaxSendBandwidthAndMaxEncodingBitrate) {
3988 send_parameters_.max_bandwidth_bps = 99999;
3989 FakeVideoSendStream* stream = AddSendStream();
3990 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
3991 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
3992 ASSERT_EQ(1u, stream->GetVideoStreams().size());
3993 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
3994 stream->GetVideoStreams()[0].max_bitrate_bps);
3995
3996 // Get and set the rtp encoding parameters.
3997 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
3998 EXPECT_EQ(1u, parameters.encodings.size());
3999
4000 parameters.encodings[0].max_bitrate_bps = 99999 - 1;
4001 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4002 EXPECT_EQ(parameters.encodings[0].max_bitrate_bps,
4003 stream->GetVideoStreams()[0].max_bitrate_bps);
4004
4005 parameters.encodings[0].max_bitrate_bps = 99999 + 1;
4006 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4007 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4008 stream->GetVideoStreams()[0].max_bitrate_bps);
4009}
4010
eladalonf1841382017-06-12 01:16:46 -07004011TEST_F(WebRtcVideoChannelTest, SetMaxSendBitrateCanIncreaseSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004012 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004013 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004014 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004015 channel_->SetSend(true);
4016
4017 FakeVideoSendStream* stream = AddSendStream();
4018
Niels Möller805a27e2019-01-21 12:21:27 +01004019 webrtc::test::FrameForwarder frame_forwarder;
4020 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Peter Boström3afc8c42016-01-27 16:45:21 +01004021
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004022 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
4023 int initial_max_bitrate_bps = streams[0].max_bitrate_bps;
4024 EXPECT_GT(initial_max_bitrate_bps, 0);
4025
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004026 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
4027 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01004028 // Insert a frame to update the encoder config.
Niels Möller805a27e2019-01-21 12:21:27 +01004029 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004030 streams = stream->GetVideoStreams();
4031 EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps);
Niels Möllerff40b142018-04-09 08:49:14 +02004032 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004033}
4034
eladalonf1841382017-06-12 01:16:46 -07004035TEST_F(WebRtcVideoChannelTest,
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004036 SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004037 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004038 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004039 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004040 channel_->SetSend(true);
4041
4042 FakeVideoSendStream* stream = AddSendStream(
4043 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
4044
4045 // Send a frame to make sure this scales up to >1 stream (simulcast).
Niels Möller805a27e2019-01-21 12:21:27 +01004046 webrtc::test::FrameForwarder frame_forwarder;
4047 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], nullptr, &frame_forwarder));
4048 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004049
4050 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
4051 ASSERT_GT(streams.size(), 1u)
4052 << "Without simulcast this test doesn't make sense.";
pbosbe16f792015-10-16 12:49:39 -07004053 int initial_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004054 EXPECT_GT(initial_max_bitrate_bps, 0);
4055
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004056 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
4057 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01004058 // Insert a frame to update the encoder config.
Niels Möller805a27e2019-01-21 12:21:27 +01004059 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004060 streams = stream->GetVideoStreams();
pbosbe16f792015-10-16 12:49:39 -07004061 int increased_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004062 EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps);
4063
Niels Möllerff40b142018-04-09 08:49:14 +02004064 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004065}
4066
eladalonf1841382017-06-12 01:16:46 -07004067TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithMaxQuantization) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004068 static const char* kMaxQuantization = "21";
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004069 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004070 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004071 parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
4072 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Mirko Bonadeif859e552018-05-30 15:31:29 +02004073 EXPECT_EQ(atoi(kMaxQuantization),
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00004074 AddSendStream()->GetVideoStreams().back().max_qp);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004075
4076 VideoCodec codec;
4077 EXPECT_TRUE(channel_->GetSendCodec(&codec));
4078 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
4079}
4080
eladalonf1841382017-06-12 01:16:46 -07004081TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectBadPayloadTypes) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004082 // TODO(pbos): Should we only allow the dynamic range?
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00004083 static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004084 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004085 parameters.codecs.push_back(GetEngineCodec("VP8"));
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00004086 for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004087 parameters.codecs[0].id = kIncorrectPayloads[i];
4088 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pkasting@chromium.orgd3245462015-02-23 21:28:22 +00004089 << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004090 }
4091}
4092
eladalonf1841382017-06-12 01:16:46 -07004093TEST_F(WebRtcVideoChannelTest, SetSendCodecsAcceptAllValidPayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004094 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004095 parameters.codecs.push_back(GetEngineCodec("VP8"));
magjedf823ede2016-11-12 09:53:04 -08004096 for (int payload_type = 96; payload_type <= 127; ++payload_type) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004097 parameters.codecs[0].id = payload_type;
4098 EXPECT_TRUE(channel_->SetSendParameters(parameters))
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004099 << "Payload type '" << payload_type << "' rejected.";
4100 }
4101}
4102
deadbeef67cf2c12016-04-13 10:07:16 -07004103// Test that setting the a different set of codecs but with an identical front
4104// codec doesn't result in the stream being recreated.
4105// This may happen when a subsequent negotiation includes fewer codecs, as a
4106// result of one of the codecs being rejected.
eladalonf1841382017-06-12 01:16:46 -07004107TEST_F(WebRtcVideoChannelTest,
deadbeef67cf2c12016-04-13 10:07:16 -07004108 SetSendCodecsIdenticalFirstCodecDoesntRecreateStream) {
4109 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08004110 parameters1.codecs.push_back(GetEngineCodec("VP8"));
4111 parameters1.codecs.push_back(GetEngineCodec("VP9"));
deadbeef67cf2c12016-04-13 10:07:16 -07004112 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
4113
4114 AddSendStream();
4115 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
4116
4117 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08004118 parameters2.codecs.push_back(GetEngineCodec("VP8"));
deadbeef67cf2c12016-04-13 10:07:16 -07004119 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
4120 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
4121}
4122
eladalonf1841382017-06-12 01:16:46 -07004123TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithOnlyVp8) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004124 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004125 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004126 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004127}
4128
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004129// Test that we set our inbound RTX codecs properly.
eladalonf1841382017-06-12 01:16:46 -07004130TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithRtx) {
magjed509e4fe2016-11-18 01:34:11 -08004131 const int kUnusedPayloadType1 = 126;
4132 const int kUnusedPayloadType2 = 127;
4133 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
4134 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
4135
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004136 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004137 parameters.codecs.push_back(GetEngineCodec("VP8"));
4138 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004139 parameters.codecs.push_back(rtx_codec);
4140 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004141 << "RTX codec without associated payload should be rejected.";
4142
magjed509e4fe2016-11-18 01:34:11 -08004143 parameters.codecs[1].SetParam("apt", kUnusedPayloadType2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004144 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004145 << "RTX codec with invalid associated payload type should be rejected.";
4146
magjed509e4fe2016-11-18 01:34:11 -08004147 parameters.codecs[1].SetParam("apt", GetEngineCodec("VP8").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004148 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004149
magjed509e4fe2016-11-18 01:34:11 -08004150 cricket::VideoCodec rtx_codec2(kUnusedPayloadType2, "rtx");
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004151 rtx_codec2.SetParam("apt", rtx_codec.id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004152 parameters.codecs.push_back(rtx_codec2);
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004153
Yves Gerey665174f2018-06-19 15:03:05 +02004154 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
4155 << "RTX codec with another RTX as associated payload type should be "
4156 "rejected.";
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004157}
4158
eladalonf1841382017-06-12 01:16:46 -07004159TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithChangedRtxPayloadType) {
brandtr14742122017-01-27 04:53:07 -08004160 const int kUnusedPayloadType1 = 126;
4161 const int kUnusedPayloadType2 = 127;
4162 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
4163 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
4164
4165 // SSRCs for RTX.
4166 cricket::StreamParams params =
4167 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
4168 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
4169 AddRecvStream(params);
4170
4171 // Original payload type for RTX.
4172 cricket::VideoRecvParameters parameters;
4173 parameters.codecs.push_back(GetEngineCodec("VP8"));
4174 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
4175 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
4176 parameters.codecs.push_back(rtx_codec);
4177 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4178 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
4179 const webrtc::VideoReceiveStream::Config& config_before =
4180 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
nisse26e3abb2017-08-25 04:44:25 -07004181 EXPECT_EQ(1U, config_before.rtp.rtx_associated_payload_types.size());
4182 const int* payload_type_before = FindKeyByValue(
4183 config_before.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
4184 ASSERT_NE(payload_type_before, nullptr);
4185 EXPECT_EQ(kUnusedPayloadType1, *payload_type_before);
brandtr14742122017-01-27 04:53:07 -08004186 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx_ssrc);
4187
4188 // Change payload type for RTX.
4189 parameters.codecs[1].id = kUnusedPayloadType2;
4190 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4191 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
4192 const webrtc::VideoReceiveStream::Config& config_after =
4193 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
nisse26e3abb2017-08-25 04:44:25 -07004194 EXPECT_EQ(1U, config_after.rtp.rtx_associated_payload_types.size());
4195 const int* payload_type_after = FindKeyByValue(
4196 config_after.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
4197 ASSERT_NE(payload_type_after, nullptr);
4198 EXPECT_EQ(kUnusedPayloadType2, *payload_type_after);
brandtr14742122017-01-27 04:53:07 -08004199 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx_ssrc);
4200}
4201
eladalonf1841382017-06-12 01:16:46 -07004202TEST_F(WebRtcVideoChannelTest, SetRecvCodecsDifferentPayloadType) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004203 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004204 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004205 parameters.codecs[0].id = 99;
4206 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004207}
4208
eladalonf1841382017-06-12 01:16:46 -07004209TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptDefaultCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004210 cricket::VideoRecvParameters parameters;
4211 parameters.codecs = engine_.codecs();
4212 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00004213
4214 FakeVideoReceiveStream* stream = AddRecvStream();
Tommi733b5472016-06-10 17:58:01 +02004215 const webrtc::VideoReceiveStream::Config& config = stream->GetConfig();
Niels Möllercb7e1d22018-09-11 15:56:04 +02004216 EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].video_format.name);
pbos@webrtc.org776e6f22014-10-29 15:28:39 +00004217 EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004218}
4219
eladalonf1841382017-06-12 01:16:46 -07004220TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectUnsupportedCodec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004221 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004222 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj26752742016-10-24 01:21:16 -07004223 parameters.codecs.push_back(VideoCodec(101, "WTF3"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004224 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004225}
4226
eladalonf1841382017-06-12 01:16:46 -07004227TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptsMultipleVideoCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004228 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004229 parameters.codecs.push_back(GetEngineCodec("VP8"));
4230 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004231 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004232}
4233
eladalonf1841382017-06-12 01:16:46 -07004234TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004235 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004236 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4237 send_parameters.codecs.push_back(GetEngineCodec("red"));
4238 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004239 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004240
4241 FakeVideoReceiveStream* stream = AddRecvStream();
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004242
magjed509e4fe2016-11-18 01:34:11 -08004243 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004244 stream->GetConfig().rtp.ulpfec_payload_type);
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004245
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004246 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004247 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004248 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00004249 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08004250 ASSERT_TRUE(stream != nullptr);
nisse3b3622f2017-09-26 02:49:21 -07004251 EXPECT_EQ(-1, stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004252 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
4253}
4254
eladalonf1841382017-06-12 01:16:46 -07004255TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvParamsWithoutFecDisablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08004256 AddRecvStream(
4257 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08004258 const std::vector<FakeFlexfecReceiveStream*>& streams =
brandtr468da7c2016-11-22 02:16:47 -08004259 fake_call_->GetFlexfecReceiveStreams();
4260
4261 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004262 const FakeFlexfecReceiveStream* stream = streams.front();
4263 EXPECT_EQ(GetEngineCodec("flexfec-03").id, stream->GetConfig().payload_type);
4264 EXPECT_EQ(kFlexfecSsrc, stream->GetConfig().remote_ssrc);
4265 ASSERT_EQ(1U, stream->GetConfig().protected_media_ssrcs.size());
4266 EXPECT_EQ(kSsrcs1[0], stream->GetConfig().protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08004267
4268 cricket::VideoRecvParameters recv_parameters;
4269 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4270 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4271 EXPECT_TRUE(streams.empty())
4272 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.org269605c2014-06-26 08:49:03 +00004273}
4274
eladalonf1841382017-06-12 01:16:46 -07004275TEST_F(WebRtcVideoChannelTest, SetSendParamsWithFecEnablesFec) {
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004276 FakeVideoReceiveStream* stream = AddRecvStream();
magjed509e4fe2016-11-18 01:34:11 -08004277 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004278 stream->GetConfig().rtp.ulpfec_payload_type);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004279
4280 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004281 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4282 recv_parameters.codecs.push_back(GetEngineCodec("red"));
4283 recv_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004284 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4285 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08004286 ASSERT_TRUE(stream != nullptr);
magjed509e4fe2016-11-18 01:34:11 -08004287 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004288 stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004289 << "ULPFEC should be enabled on the receive stream.";
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004290
4291 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004292 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4293 send_parameters.codecs.push_back(GetEngineCodec("red"));
4294 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004295 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
4296 stream = fake_call_->GetVideoReceiveStreams()[0];
magjed509e4fe2016-11-18 01:34:11 -08004297 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004298 stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004299 << "ULPFEC should be enabled on the receive stream.";
4300}
4301
eladalonf1841382017-06-12 01:16:46 -07004302TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07004303 SetSendRecvParamsWithFecEnablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08004304 AddRecvStream(
4305 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08004306 const std::vector<FakeFlexfecReceiveStream*>& streams =
brandtr468da7c2016-11-22 02:16:47 -08004307 fake_call_->GetFlexfecReceiveStreams();
4308
4309 cricket::VideoRecvParameters recv_parameters;
4310 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4311 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4312 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4313 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004314 const FakeFlexfecReceiveStream* stream_with_recv_params = streams.front();
brandtr468da7c2016-11-22 02:16:47 -08004315 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9c3d4c42017-01-23 06:59:13 -08004316 stream_with_recv_params->GetConfig().payload_type);
4317 EXPECT_EQ(kFlexfecSsrc, stream_with_recv_params->GetConfig().remote_ssrc);
brandtr468da7c2016-11-22 02:16:47 -08004318 EXPECT_EQ(1U,
brandtr9c3d4c42017-01-23 06:59:13 -08004319 stream_with_recv_params->GetConfig().protected_media_ssrcs.size());
brandtr468da7c2016-11-22 02:16:47 -08004320 EXPECT_EQ(kSsrcs1[0],
brandtr9c3d4c42017-01-23 06:59:13 -08004321 stream_with_recv_params->GetConfig().protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08004322
4323 cricket::VideoSendParameters send_parameters;
4324 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4325 send_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4326 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
4327 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004328 const FakeFlexfecReceiveStream* stream_with_send_params = streams.front();
brandtr468da7c2016-11-22 02:16:47 -08004329 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9c3d4c42017-01-23 06:59:13 -08004330 stream_with_send_params->GetConfig().payload_type);
4331 EXPECT_EQ(kFlexfecSsrc, stream_with_send_params->GetConfig().remote_ssrc);
brandtr468da7c2016-11-22 02:16:47 -08004332 EXPECT_EQ(1U,
brandtr9c3d4c42017-01-23 06:59:13 -08004333 stream_with_send_params->GetConfig().protected_media_ssrcs.size());
brandtr468da7c2016-11-22 02:16:47 -08004334 EXPECT_EQ(kSsrcs1[0],
brandtr9c3d4c42017-01-23 06:59:13 -08004335 stream_with_send_params->GetConfig().protected_media_ssrcs[0]);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004336}
4337
eladalonf1841382017-06-12 01:16:46 -07004338TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateFecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004339 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004340 parameters.codecs.push_back(GetEngineCodec("VP8"));
4341 parameters.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004342 parameters.codecs[1].id = parameters.codecs[0].id;
4343 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004344}
4345
eladalonf1841382017-06-12 01:16:46 -07004346TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07004347 SetRecvCodecsRejectDuplicateFecPayloads) {
brandtr468da7c2016-11-22 02:16:47 -08004348 cricket::VideoRecvParameters parameters;
4349 parameters.codecs.push_back(GetEngineCodec("VP8"));
4350 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4351 parameters.codecs[1].id = parameters.codecs[0].id;
4352 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
4353}
4354
eladalonf1841382017-06-12 01:16:46 -07004355TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateCodecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004356 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004357 parameters.codecs.push_back(GetEngineCodec("VP8"));
4358 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004359 parameters.codecs[1].id = parameters.codecs[0].id;
4360 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004361}
4362
eladalonf1841382017-06-12 01:16:46 -07004363TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004364 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004365 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004366 parameters.codecs.push_back(GetEngineCodec("VP8"));
4367 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004368 parameters.codecs[1].id += 1;
4369 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004370}
4371
deadbeef67cf2c12016-04-13 10:07:16 -07004372// Test that setting the same codecs but with a different order
deadbeef874ca3a2015-08-20 17:19:20 -07004373// doesn't result in the stream being recreated.
eladalonf1841382017-06-12 01:16:46 -07004374TEST_F(WebRtcVideoChannelTest,
deadbeef67cf2c12016-04-13 10:07:16 -07004375 SetRecvCodecsDifferentOrderDoesntRecreateStream) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004376 cricket::VideoRecvParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08004377 parameters1.codecs.push_back(GetEngineCodec("VP8"));
4378 parameters1.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004379 EXPECT_TRUE(channel_->SetRecvParameters(parameters1));
deadbeef874ca3a2015-08-20 17:19:20 -07004380
4381 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
4382 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
4383
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004384 cricket::VideoRecvParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08004385 parameters2.codecs.push_back(GetEngineCodec("red"));
4386 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004387 EXPECT_TRUE(channel_->SetRecvParameters(parameters2));
deadbeef874ca3a2015-08-20 17:19:20 -07004388 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
4389}
4390
eladalonf1841382017-06-12 01:16:46 -07004391TEST_F(WebRtcVideoChannelTest, SendStreamNotSendingByDefault) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004392 EXPECT_FALSE(AddSendStream()->IsSending());
4393}
4394
eladalonf1841382017-06-12 01:16:46 -07004395TEST_F(WebRtcVideoChannelTest, ReceiveStreamReceivingByDefault) {
pbos@webrtc.org85f42942014-07-22 09:14:58 +00004396 EXPECT_TRUE(AddRecvStream()->IsReceiving());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004397}
4398
eladalonf1841382017-06-12 01:16:46 -07004399TEST_F(WebRtcVideoChannelTest, SetSend) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +00004400 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004401 EXPECT_FALSE(stream->IsSending());
4402
4403 // false->true
4404 EXPECT_TRUE(channel_->SetSend(true));
4405 EXPECT_TRUE(stream->IsSending());
4406 // true->true
4407 EXPECT_TRUE(channel_->SetSend(true));
4408 EXPECT_TRUE(stream->IsSending());
4409 // true->false
4410 EXPECT_TRUE(channel_->SetSend(false));
4411 EXPECT_FALSE(stream->IsSending());
4412 // false->false
4413 EXPECT_TRUE(channel_->SetSend(false));
4414 EXPECT_FALSE(stream->IsSending());
4415
4416 EXPECT_TRUE(channel_->SetSend(true));
4417 FakeVideoSendStream* new_stream = AddSendStream();
4418 EXPECT_TRUE(new_stream->IsSending())
4419 << "Send stream created after SetSend(true) not sending initially.";
4420}
4421
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00004422// This test verifies DSCP settings are properly applied on video media channel.
eladalonf1841382017-06-12 01:16:46 -07004423TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
kwiberg686a8ef2016-02-26 03:00:35 -08004424 std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00004425 new cricket::FakeNetworkInterface);
nisse51542be2016-02-12 02:27:06 -08004426 MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07004427 std::unique_ptr<cricket::WebRtcVideoChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07004428 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08004429
Sebastian Jansson84848f22018-11-16 10:40:36 +01004430 channel.reset(
4431 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
4432 call_.get(), config, VideoOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07004433 channel->SetInterface(network_interface.get(), /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08004434 // Default value when DSCP is disabled should be DSCP_DEFAULT.
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00004435 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
nisse51542be2016-02-12 02:27:06 -08004436
Tim Haloun648d28a2018-10-18 16:52:22 -07004437 // Default value when DSCP is enabled is also DSCP_DEFAULT, until it is set
4438 // through rtp parameters.
nisse51542be2016-02-12 02:27:06 -08004439 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01004440 channel.reset(
4441 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
4442 call_.get(), config, VideoOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07004443 channel->SetInterface(network_interface.get(), /*media_transport=*/nullptr);
Tim Haloun648d28a2018-10-18 16:52:22 -07004444 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
4445
4446 // Create a send stream to configure
4447 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
4448 parameters = channel->GetRtpSendParameters(kSsrc);
4449 ASSERT_FALSE(parameters.encodings.empty());
4450
4451 // Various priorities map to various dscp values.
4452 parameters.encodings[0].network_priority = 4.0;
4453 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08004454 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07004455 parameters.encodings[0].network_priority = 0.5;
4456 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
4457 EXPECT_EQ(rtc::DSCP_CS1, network_interface->dscp());
4458
4459 // A bad priority does not change the dscp value.
4460 parameters.encodings[0].network_priority = 0.0;
4461 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
4462 EXPECT_EQ(rtc::DSCP_CS1, network_interface->dscp());
nisse51542be2016-02-12 02:27:06 -08004463
Tim Haloun6ca98362018-09-17 17:06:08 -07004464 // Packets should also self-identify their dscp in PacketOptions.
4465 const uint8_t kData[10] = {0};
4466 EXPECT_TRUE(static_cast<webrtc::Transport*>(channel.get())
4467 ->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07004468 EXPECT_EQ(rtc::DSCP_CS1, network_interface->options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07004469
nisse51542be2016-02-12 02:27:06 -08004470 // Verify that setting the option to false resets the
4471 // DiffServCodePoint.
4472 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01004473 channel.reset(
4474 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
4475 call_.get(), config, VideoOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07004476 channel->SetInterface(network_interface.get(), /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08004477 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004478}
4479
deadbeef13871492015-12-09 12:37:51 -08004480// This test verifies that the RTCP reduced size mode is properly applied to
4481// send video streams.
eladalonf1841382017-06-12 01:16:46 -07004482TEST_F(WebRtcVideoChannelTest, TestSetSendRtcpReducedSize) {
deadbeef13871492015-12-09 12:37:51 -08004483 // Create stream, expecting that default mode is "compound".
4484 FakeVideoSendStream* stream1 = AddSendStream();
4485 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
Florent Castellidacec712018-05-24 16:24:21 +02004486 webrtc::RtpParameters rtp_parameters =
4487 channel_->GetRtpSendParameters(last_ssrc_);
4488 EXPECT_FALSE(rtp_parameters.rtcp.reduced_size);
deadbeef13871492015-12-09 12:37:51 -08004489
4490 // Now enable reduced size mode.
4491 send_parameters_.rtcp.reduced_size = true;
4492 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
4493 stream1 = fake_call_->GetVideoSendStreams()[0];
4494 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
Florent Castellidacec712018-05-24 16:24:21 +02004495 rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
4496 EXPECT_TRUE(rtp_parameters.rtcp.reduced_size);
deadbeef13871492015-12-09 12:37:51 -08004497
4498 // Create a new stream and ensure it picks up the reduced size mode.
4499 FakeVideoSendStream* stream2 = AddSendStream();
4500 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
4501}
4502
4503// This test verifies that the RTCP reduced size mode is properly applied to
4504// receive video streams.
eladalonf1841382017-06-12 01:16:46 -07004505TEST_F(WebRtcVideoChannelTest, TestSetRecvRtcpReducedSize) {
deadbeef13871492015-12-09 12:37:51 -08004506 // Create stream, expecting that default mode is "compound".
4507 FakeVideoReceiveStream* stream1 = AddRecvStream();
4508 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
4509
4510 // Now enable reduced size mode.
Taylor Brandstetter5f0b83b2016-03-18 15:02:07 -07004511 // TODO(deadbeef): Once "recv_parameters" becomes "receiver_parameters",
4512 // the reduced_size flag should come from that.
4513 send_parameters_.rtcp.reduced_size = true;
4514 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
deadbeef13871492015-12-09 12:37:51 -08004515 stream1 = fake_call_->GetVideoReceiveStreams()[0];
4516 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
4517
4518 // Create a new stream and ensure it picks up the reduced size mode.
4519 FakeVideoReceiveStream* stream2 = AddRecvStream();
4520 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
4521}
4522
eladalonf1841382017-06-12 01:16:46 -07004523TEST_F(WebRtcVideoChannelTest, OnReadyToSendSignalsNetworkState) {
skvlad7a43d252016-03-22 15:32:27 -07004524 EXPECT_EQ(webrtc::kNetworkUp,
4525 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
4526 EXPECT_EQ(webrtc::kNetworkUp,
4527 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00004528
4529 channel_->OnReadyToSend(false);
skvlad7a43d252016-03-22 15:32:27 -07004530 EXPECT_EQ(webrtc::kNetworkDown,
4531 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
4532 EXPECT_EQ(webrtc::kNetworkUp,
4533 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00004534
4535 channel_->OnReadyToSend(true);
skvlad7a43d252016-03-22 15:32:27 -07004536 EXPECT_EQ(webrtc::kNetworkUp,
4537 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
4538 EXPECT_EQ(webrtc::kNetworkUp,
4539 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004540}
4541
eladalonf1841382017-06-12 01:16:46 -07004542TEST_F(WebRtcVideoChannelTest, GetStatsReportsSentCodecName) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004543 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004544 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004545 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström74d9ed72015-03-26 16:28:31 +01004546
4547 AddSendStream();
4548
4549 cricket::VideoMediaInfo info;
4550 ASSERT_TRUE(channel_->GetStats(&info));
magjed509e4fe2016-11-18 01:34:11 -08004551 EXPECT_EQ("VP8", info.senders[0].codec_name);
Peter Boström74d9ed72015-03-26 16:28:31 +01004552}
4553
eladalonf1841382017-06-12 01:16:46 -07004554TEST_F(WebRtcVideoChannelTest, GetStatsReportsEncoderImplementationName) {
Peter Boströmb7d9a972015-12-18 16:01:11 +01004555 FakeVideoSendStream* stream = AddSendStream();
4556 webrtc::VideoSendStream::Stats stats;
4557 stats.encoder_implementation_name = "encoder_implementation_name";
4558 stream->SetStats(stats);
4559
4560 cricket::VideoMediaInfo info;
4561 ASSERT_TRUE(channel_->GetStats(&info));
4562 EXPECT_EQ(stats.encoder_implementation_name,
4563 info.senders[0].encoder_implementation_name);
4564}
4565
eladalonf1841382017-06-12 01:16:46 -07004566TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuOveruseMetrics) {
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00004567 FakeVideoSendStream* stream = AddSendStream();
4568 webrtc::VideoSendStream::Stats stats;
4569 stats.avg_encode_time_ms = 13;
4570 stats.encode_usage_percent = 42;
4571 stream->SetStats(stats);
4572
4573 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004574 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00004575 EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
4576 EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
4577}
4578
eladalonf1841382017-06-12 01:16:46 -07004579TEST_F(WebRtcVideoChannelTest, GetStatsReportsFramesEncoded) {
sakal43536c32016-10-24 01:46:43 -07004580 FakeVideoSendStream* stream = AddSendStream();
4581 webrtc::VideoSendStream::Stats stats;
4582 stats.frames_encoded = 13;
4583 stream->SetStats(stats);
4584
4585 cricket::VideoMediaInfo info;
4586 ASSERT_TRUE(channel_->GetStats(&info));
4587 EXPECT_EQ(stats.frames_encoded, info.senders[0].frames_encoded);
4588}
4589
eladalonf1841382017-06-12 01:16:46 -07004590TEST_F(WebRtcVideoChannelTest, GetStatsReportsQpSum) {
sakal87da4042016-10-31 06:53:47 -07004591 FakeVideoSendStream* stream = AddSendStream();
4592 webrtc::VideoSendStream::Stats stats;
Oskar Sundbom78807582017-11-16 11:09:55 +01004593 stats.qp_sum = 13;
sakal87da4042016-10-31 06:53:47 -07004594 stream->SetStats(stats);
4595
4596 cricket::VideoMediaInfo info;
4597 ASSERT_TRUE(channel_->GetStats(&info));
4598 EXPECT_EQ(stats.qp_sum, info.senders[0].qp_sum);
4599}
4600
eladalonf1841382017-06-12 01:16:46 -07004601TEST_F(WebRtcVideoChannelTest, GetStatsReportsUpperResolution) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00004602 FakeVideoSendStream* stream = AddSendStream();
4603 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004604 stats.substreams[17].width = 123;
4605 stats.substreams[17].height = 40;
4606 stats.substreams[42].width = 80;
4607 stats.substreams[42].height = 31;
4608 stats.substreams[11].width = 20;
4609 stats.substreams[11].height = 90;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00004610 stream->SetStats(stats);
4611
4612 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004613 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org273a4142014-12-01 15:23:21 +00004614 ASSERT_EQ(1u, info.senders.size());
4615 EXPECT_EQ(123, info.senders[0].send_frame_width);
4616 EXPECT_EQ(90, info.senders[0].send_frame_height);
4617}
4618
eladalonf1841382017-06-12 01:16:46 -07004619TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuAdaptationStats) {
perkj803d97f2016-11-01 11:45:46 -07004620 FakeVideoSendStream* stream = AddSendStream();
4621 webrtc::VideoSendStream::Stats stats;
4622 stats.number_of_cpu_adapt_changes = 2;
4623 stats.cpu_limited_resolution = true;
4624 stream->SetStats(stats);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004625
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004626 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004627 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004628 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07004629 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU, info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07004630 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004631}
4632
eladalonf1841382017-06-12 01:16:46 -07004633TEST_F(WebRtcVideoChannelTest, GetStatsReportsAdaptationAndBandwidthStats) {
perkj803d97f2016-11-01 11:45:46 -07004634 FakeVideoSendStream* stream = AddSendStream();
asapersson17821db2015-12-14 02:08:12 -08004635 webrtc::VideoSendStream::Stats stats;
perkj803d97f2016-11-01 11:45:46 -07004636 stats.number_of_cpu_adapt_changes = 2;
4637 stats.cpu_limited_resolution = true;
asapersson17821db2015-12-14 02:08:12 -08004638 stats.bw_limited_resolution = true;
perkj803d97f2016-11-01 11:45:46 -07004639 stream->SetStats(stats);
4640
4641 cricket::VideoMediaInfo info;
asapersson17821db2015-12-14 02:08:12 -08004642 EXPECT_TRUE(channel_->GetStats(&info));
4643 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07004644 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU |
4645 WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08004646 info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07004647 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
asapersson17821db2015-12-14 02:08:12 -08004648}
4649
eladalonf1841382017-06-12 01:16:46 -07004650TEST_F(WebRtcVideoChannelTest,
asapersson17821db2015-12-14 02:08:12 -08004651 GetStatsTranslatesBandwidthLimitedResolutionCorrectly) {
4652 FakeVideoSendStream* stream = AddSendStream();
4653 webrtc::VideoSendStream::Stats stats;
4654 stats.bw_limited_resolution = true;
4655 stream->SetStats(stats);
4656
4657 cricket::VideoMediaInfo info;
4658 EXPECT_TRUE(channel_->GetStats(&info));
4659 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07004660 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08004661 info.senders[0].adapt_reason);
4662}
4663
Yves Gerey665174f2018-06-19 15:03:05 +02004664TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesSendRtcpPacketTypesCorrectly) {
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004665 FakeVideoSendStream* stream = AddSendStream();
4666 webrtc::VideoSendStream::Stats stats;
4667 stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2;
4668 stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3;
4669 stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4;
4670
4671 stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5;
4672 stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7;
4673 stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9;
4674
4675 stream->SetStats(stats);
4676
4677 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004678 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004679 EXPECT_EQ(7, info.senders[0].firs_rcvd);
4680 EXPECT_EQ(10, info.senders[0].nacks_rcvd);
4681 EXPECT_EQ(13, info.senders[0].plis_rcvd);
4682}
4683
eladalonf1841382017-06-12 01:16:46 -07004684TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004685 GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) {
4686 FakeVideoReceiveStream* stream = AddRecvStream();
4687 webrtc::VideoReceiveStream::Stats stats;
4688 stats.rtcp_packet_type_counts.fir_packets = 2;
4689 stats.rtcp_packet_type_counts.nack_packets = 3;
4690 stats.rtcp_packet_type_counts.pli_packets = 4;
4691 stream->SetStats(stats);
4692
4693 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004694 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004695 EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004696 rtc::checked_cast<unsigned int>(info.receivers[0].firs_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004697 EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004698 rtc::checked_cast<unsigned int>(info.receivers[0].nacks_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004699 EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004700 rtc::checked_cast<unsigned int>(info.receivers[0].plis_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004701}
4702
eladalonf1841382017-06-12 01:16:46 -07004703TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesDecodeStatsCorrectly) {
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004704 FakeVideoReceiveStream* stream = AddRecvStream();
4705 webrtc::VideoReceiveStream::Stats stats;
Peter Boströmb7d9a972015-12-18 16:01:11 +01004706 stats.decoder_implementation_name = "decoder_implementation_name";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004707 stats.decode_ms = 2;
4708 stats.max_decode_ms = 3;
4709 stats.current_delay_ms = 4;
4710 stats.target_delay_ms = 5;
4711 stats.jitter_buffer_ms = 6;
4712 stats.min_playout_delay_ms = 7;
4713 stats.render_delay_ms = 8;
asapersson26dd92b2016-08-30 00:45:45 -07004714 stats.width = 9;
4715 stats.height = 10;
hbos42f6d2f2017-01-20 03:56:50 -08004716 stats.frame_counts.key_frames = 11;
4717 stats.frame_counts.delta_frames = 12;
hbos50cfe1f2017-01-23 07:21:55 -08004718 stats.frames_rendered = 13;
4719 stats.frames_decoded = 14;
Oskar Sundbom78807582017-11-16 11:09:55 +01004720 stats.qp_sum = 15;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004721 stream->SetStats(stats);
4722
4723 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004724 ASSERT_TRUE(channel_->GetStats(&info));
Peter Boströmb7d9a972015-12-18 16:01:11 +01004725 EXPECT_EQ(stats.decoder_implementation_name,
4726 info.receivers[0].decoder_implementation_name);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004727 EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
4728 EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
4729 EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
4730 EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
4731 EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
4732 EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
4733 EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
asapersson26dd92b2016-08-30 00:45:45 -07004734 EXPECT_EQ(stats.width, info.receivers[0].frame_width);
4735 EXPECT_EQ(stats.height, info.receivers[0].frame_height);
Mirko Bonadeif859e552018-05-30 15:31:29 +02004736 EXPECT_EQ(rtc::checked_cast<unsigned int>(stats.frame_counts.key_frames +
4737 stats.frame_counts.delta_frames),
hbos42f6d2f2017-01-20 03:56:50 -08004738 info.receivers[0].frames_received);
hbos50cfe1f2017-01-23 07:21:55 -08004739 EXPECT_EQ(stats.frames_rendered, info.receivers[0].frames_rendered);
sakale5ba44e2016-10-26 07:09:24 -07004740 EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded);
sakalcc452e12017-02-09 04:53:45 -08004741 EXPECT_EQ(stats.qp_sum, info.receivers[0].qp_sum);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004742}
4743
eladalonf1841382017-06-12 01:16:46 -07004744TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesReceivePacketStatsCorrectly) {
Peter Boström393347f2015-04-22 14:52:45 +02004745 FakeVideoReceiveStream* stream = AddRecvStream();
4746 webrtc::VideoReceiveStream::Stats stats;
4747 stats.rtp_stats.transmitted.payload_bytes = 2;
4748 stats.rtp_stats.transmitted.header_bytes = 3;
4749 stats.rtp_stats.transmitted.padding_bytes = 4;
4750 stats.rtp_stats.transmitted.packets = 5;
srte186d9c32017-08-04 05:03:53 -07004751 stats.rtcp_stats.packets_lost = 6;
Peter Boström393347f2015-04-22 14:52:45 +02004752 stats.rtcp_stats.fraction_lost = 7;
4753 stream->SetStats(stats);
4754
4755 cricket::VideoMediaInfo info;
4756 ASSERT_TRUE(channel_->GetStats(&info));
4757 EXPECT_EQ(stats.rtp_stats.transmitted.payload_bytes +
4758 stats.rtp_stats.transmitted.header_bytes +
4759 stats.rtp_stats.transmitted.padding_bytes,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004760 rtc::checked_cast<size_t>(info.receivers[0].bytes_rcvd));
Peter Boström393347f2015-04-22 14:52:45 +02004761 EXPECT_EQ(stats.rtp_stats.transmitted.packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004762 rtc::checked_cast<unsigned int>(info.receivers[0].packets_rcvd));
srte186d9c32017-08-04 05:03:53 -07004763 EXPECT_EQ(stats.rtcp_stats.packets_lost, info.receivers[0].packets_lost);
Mirko Bonadeif859e552018-05-30 15:31:29 +02004764 EXPECT_EQ(rtc::checked_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8),
Peter Boström393347f2015-04-22 14:52:45 +02004765 info.receivers[0].fraction_lost);
4766}
4767
eladalonf1841382017-06-12 01:16:46 -07004768TEST_F(WebRtcVideoChannelTest, TranslatesCallStatsCorrectly) {
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00004769 AddSendStream();
4770 AddSendStream();
4771 webrtc::Call::Stats stats;
4772 stats.rtt_ms = 123;
4773 fake_call_->SetStats(stats);
4774
4775 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004776 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00004777 ASSERT_EQ(2u, info.senders.size());
4778 EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms);
4779 EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
4780}
4781
eladalonf1841382017-06-12 01:16:46 -07004782TEST_F(WebRtcVideoChannelTest, TranslatesSenderBitrateStatsCorrectly) {
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004783 FakeVideoSendStream* stream = AddSendStream();
4784 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00004785 stats.target_media_bitrate_bps = 156;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004786 stats.media_bitrate_bps = 123;
4787 stats.substreams[17].total_bitrate_bps = 1;
4788 stats.substreams[17].retransmit_bitrate_bps = 2;
4789 stats.substreams[42].total_bitrate_bps = 3;
4790 stats.substreams[42].retransmit_bitrate_bps = 4;
4791 stream->SetStats(stats);
4792
4793 FakeVideoSendStream* stream2 = AddSendStream();
4794 webrtc::VideoSendStream::Stats stats2;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00004795 stats2.target_media_bitrate_bps = 200;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004796 stats2.media_bitrate_bps = 321;
4797 stats2.substreams[13].total_bitrate_bps = 5;
4798 stats2.substreams[13].retransmit_bitrate_bps = 6;
4799 stats2.substreams[21].total_bitrate_bps = 7;
4800 stats2.substreams[21].retransmit_bitrate_bps = 8;
4801 stream2->SetStats(stats2);
4802
4803 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004804 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004805 ASSERT_EQ(2u, info.senders.size());
stefanf79ade12017-06-02 06:44:03 -07004806 BandwidthEstimationInfo bwe_info;
4807 channel_->FillBitrateInfo(&bwe_info);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004808 // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
4809 // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
4810 EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate);
4811 EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate);
pbos@webrtc.org891d4832015-02-26 13:15:22 +00004812 EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
stefanf79ade12017-06-02 06:44:03 -07004813 bwe_info.target_enc_bitrate);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004814 EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
stefanf79ade12017-06-02 06:44:03 -07004815 bwe_info.actual_enc_bitrate);
4816 EXPECT_EQ(1 + 3 + 5 + 7, bwe_info.transmit_bitrate)
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004817 << "Bandwidth stats should take all streams into account.";
stefanf79ade12017-06-02 06:44:03 -07004818 EXPECT_EQ(2 + 4 + 6 + 8, bwe_info.retransmit_bitrate)
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004819 << "Bandwidth stats should take all streams into account.";
4820}
4821
eladalonf1841382017-06-12 01:16:46 -07004822TEST_F(WebRtcVideoChannelTest, DefaultReceiveStreamReconfiguresToUseRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004823 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00004824
Peter Boström0c4e06b2015-10-07 12:23:21 +02004825 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
4826 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00004827
4828 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
4829 const size_t kDataLength = 12;
4830 uint8_t data[kDataLength];
4831 memset(data, 0, sizeof(data));
4832 rtc::SetBE32(&data[8], ssrcs[0]);
jbaucheec21bd2016-03-20 06:15:43 -07004833 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Niels Möllere6933812018-11-05 13:01:41 +01004834 channel_->OnPacketReceived(&packet, /* packet_time_us */ -1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00004835
4836 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
4837 << "No default receive stream created.";
4838 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr14742122017-01-27 04:53:07 -08004839 EXPECT_EQ(0u, recv_stream->GetConfig().rtp.rtx_ssrc)
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00004840 << "Default receive stream should not have configured RTX";
4841
4842 EXPECT_TRUE(channel_->AddRecvStream(
4843 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
4844 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
brandtr14742122017-01-27 04:53:07 -08004845 << "AddRecvStream should have reconfigured, not added a new receiver.";
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00004846 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
nisse26e3abb2017-08-25 04:44:25 -07004847 EXPECT_FALSE(
4848 recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
nisseca5706d2017-09-11 02:32:16 -07004849 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
Peter Boströmd8b01092016-05-12 16:44:36 +02004850 << "RTX should be mapped for all decoders/payload types.";
nisseca5706d2017-09-11 02:32:16 -07004851 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02004852 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07004853 << "RTX should be mapped also for the RED payload type";
brandtr14742122017-01-27 04:53:07 -08004854 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00004855}
4856
eladalonf1841382017-06-12 01:16:46 -07004857TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithMissingSsrcsForRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004858 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd4362cd2015-03-25 14:17:23 +01004859
Peter Boström0c4e06b2015-10-07 12:23:21 +02004860 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
4861 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd4362cd2015-03-25 14:17:23 +01004862
4863 StreamParams sp =
4864 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
4865 sp.ssrcs = ssrcs; // Without RTXs, this is the important part.
4866
4867 EXPECT_FALSE(channel_->AddSendStream(sp));
4868 EXPECT_FALSE(channel_->AddRecvStream(sp));
4869}
4870
eladalonf1841382017-06-12 01:16:46 -07004871TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithOverlappingRtxSsrcs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004872 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01004873
Peter Boström0c4e06b2015-10-07 12:23:21 +02004874 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
4875 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd6f4c252015-03-26 16:23:04 +01004876
4877 StreamParams sp =
4878 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
4879
4880 EXPECT_TRUE(channel_->AddSendStream(sp));
4881 EXPECT_TRUE(channel_->AddRecvStream(sp));
4882
4883 // The RTX SSRC is already used in previous streams, using it should fail.
4884 sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]);
4885 EXPECT_FALSE(channel_->AddSendStream(sp));
4886 EXPECT_FALSE(channel_->AddRecvStream(sp));
4887
4888 // After removing the original stream this should be fine to add (makes sure
4889 // that RTX ssrcs are not forever taken).
4890 EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0]));
4891 EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0]));
4892 EXPECT_TRUE(channel_->AddSendStream(sp));
4893 EXPECT_TRUE(channel_->AddRecvStream(sp));
4894}
4895
eladalonf1841382017-06-12 01:16:46 -07004896TEST_F(WebRtcVideoChannelTest,
Peter Boströmd6f4c252015-03-26 16:23:04 +01004897 RejectsAddingStreamsWithOverlappingSimulcastSsrcs) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02004898 static const uint32_t kFirstStreamSsrcs[] = {1, 2, 3};
4899 static const uint32_t kOverlappingStreamSsrcs[] = {4, 3, 5};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004900 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01004901
Peter Boströmd6f4c252015-03-26 16:23:04 +01004902 StreamParams sp =
4903 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs));
4904
4905 EXPECT_TRUE(channel_->AddSendStream(sp));
4906 EXPECT_TRUE(channel_->AddRecvStream(sp));
4907
4908 // One of the SSRCs is already used in previous streams, using it should fail.
4909 sp = cricket::CreateSimStreamParams("cname",
4910 MAKE_VECTOR(kOverlappingStreamSsrcs));
4911 EXPECT_FALSE(channel_->AddSendStream(sp));
4912 EXPECT_FALSE(channel_->AddRecvStream(sp));
4913
4914 // After removing the original stream this should be fine to add (makes sure
4915 // that RTX ssrcs are not forever taken).
Peter Boström3548dd22015-05-22 18:48:36 +02004916 EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0]));
4917 EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0]));
Peter Boströmd6f4c252015-03-26 16:23:04 +01004918 EXPECT_TRUE(channel_->AddSendStream(sp));
4919 EXPECT_TRUE(channel_->AddRecvStream(sp));
4920}
4921
eladalonf1841382017-06-12 01:16:46 -07004922TEST_F(WebRtcVideoChannelTest, ReportsSsrcGroupsInStats) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004923 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström259bd202015-05-28 13:39:50 +02004924
4925 static const uint32_t kSenderSsrcs[] = {4, 7, 10};
4926 static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11};
4927
4928 StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams(
4929 "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs));
4930
4931 EXPECT_TRUE(channel_->AddSendStream(sender_sp));
4932
4933 static const uint32_t kReceiverSsrcs[] = {3};
4934 static const uint32_t kReceiverRtxSsrcs[] = {2};
4935
4936 StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams(
4937 "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs));
4938 EXPECT_TRUE(channel_->AddRecvStream(receiver_sp));
4939
4940 cricket::VideoMediaInfo info;
4941 ASSERT_TRUE(channel_->GetStats(&info));
4942
4943 ASSERT_EQ(1u, info.senders.size());
4944 ASSERT_EQ(1u, info.receivers.size());
4945
4946 EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups);
4947 EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups);
4948 EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
4949}
4950
eladalonf1841382017-06-12 01:16:46 -07004951TEST_F(WebRtcVideoChannelTest, MapsReceivedPayloadTypeToCodecName) {
pbosf42376c2015-08-28 07:35:32 -07004952 FakeVideoReceiveStream* stream = AddRecvStream();
4953 webrtc::VideoReceiveStream::Stats stats;
4954 cricket::VideoMediaInfo info;
4955
4956 // Report no codec name before receiving.
4957 stream->SetStats(stats);
4958 ASSERT_TRUE(channel_->GetStats(&info));
4959 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
4960
4961 // Report VP8 if we're receiving it.
magjed509e4fe2016-11-18 01:34:11 -08004962 stats.current_payload_type = GetEngineCodec("VP8").id;
pbosf42376c2015-08-28 07:35:32 -07004963 stream->SetStats(stats);
4964 ASSERT_TRUE(channel_->GetStats(&info));
4965 EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());
4966
4967 // Report no codec name for unknown playload types.
4968 stats.current_payload_type = 3;
4969 stream->SetStats(stats);
4970 ASSERT_TRUE(channel_->GetStats(&info));
4971 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
4972}
4973
Seth Hampson5897a6e2018-04-03 11:16:33 -07004974// Tests that when we add a stream without SSRCs, but contains a stream_id
4975// that it is stored and its stream id is later used when the first packet
4976// arrives to properly create a receive stream with a sync label.
4977TEST_F(WebRtcVideoChannelTest, RecvUnsignaledSsrcWithSignaledStreamId) {
4978 const char kSyncLabel[] = "sync_label";
4979 cricket::StreamParams unsignaled_stream;
4980 unsignaled_stream.set_stream_ids({kSyncLabel});
4981 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
4982 // The stream shouldn't have been created at this point because it doesn't
4983 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02004984 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07004985
4986 // Create and deliver packet.
4987 const size_t kDataLength = 12;
4988 uint8_t data[kDataLength];
4989 memset(data, 0, sizeof(data));
4990 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
4991 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Niels Möllere6933812018-11-05 13:01:41 +01004992 channel_->OnPacketReceived(&packet, /* packet_time_us */ -1);
Seth Hampson5897a6e2018-04-03 11:16:33 -07004993
4994 // The stream should now be created with the appropriate sync label.
4995 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
4996 EXPECT_EQ(kSyncLabel,
4997 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group);
4998
4999 // Removing the unsignaled stream should clear the cache. This time when
5000 // a default video receive stream is created it won't have a sync_group.
5001 ASSERT_TRUE(channel_->RemoveRecvStream(0));
5002 ASSERT_TRUE(channel_->RemoveRecvStream(kIncomingUnsignalledSsrc));
5003 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5004
Niels Möllere6933812018-11-05 13:01:41 +01005005 channel_->OnPacketReceived(&packet, /* packet_time_us */ -1);
Seth Hampson5897a6e2018-04-03 11:16:33 -07005006 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5007 EXPECT_TRUE(
5008 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group.empty());
5009}
5010
eladalonf1841382017-06-12 01:16:46 -07005011void WebRtcVideoChannelTest::TestReceiveUnsignaledSsrcPacket(
noahricd10a68e2015-07-10 11:27:55 -07005012 uint8_t payload_type,
5013 bool expect_created_receive_stream) {
magjed509e4fe2016-11-18 01:34:11 -08005014 // kRedRtxPayloadType must currently be unused.
5015 EXPECT_FALSE(FindCodecById(engine_.codecs(), kRedRtxPayloadType));
5016
noahricd10a68e2015-07-10 11:27:55 -07005017 // Add a RED RTX codec.
5018 VideoCodec red_rtx_codec =
magjed509e4fe2016-11-18 01:34:11 -08005019 VideoCodec::CreateRtxCodec(kRedRtxPayloadType, GetEngineCodec("red").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005020 recv_parameters_.codecs.push_back(red_rtx_codec);
5021 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
noahricd10a68e2015-07-10 11:27:55 -07005022
5023 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5024 const size_t kDataLength = 12;
5025 uint8_t data[kDataLength];
5026 memset(data, 0, sizeof(data));
5027
5028 rtc::Set8(data, 1, payload_type);
5029 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
jbaucheec21bd2016-03-20 06:15:43 -07005030 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Niels Möllere6933812018-11-05 13:01:41 +01005031 channel_->OnPacketReceived(&packet, /* packet_time_us */ -1);
noahricd10a68e2015-07-10 11:27:55 -07005032
5033 if (expect_created_receive_stream) {
5034 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
5035 << "Should have created a receive stream for payload type: "
5036 << payload_type;
5037 } else {
5038 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size())
5039 << "Shouldn't have created a receive stream for payload type: "
5040 << payload_type;
5041 }
5042}
5043
Åsa Persson2c7149b2018-10-15 09:36:10 +02005044class WebRtcVideoChannelDiscardUnknownSsrcTest : public WebRtcVideoChannelTest {
5045 public:
5046 WebRtcVideoChannelDiscardUnknownSsrcTest()
5047 : WebRtcVideoChannelTest(
5048 "WebRTC-Video-DiscardPacketsWithUnknownSsrc/Enabled/") {}
5049};
5050
5051TEST_F(WebRtcVideoChannelDiscardUnknownSsrcTest, NoUnsignalledStreamCreated) {
5052 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
5053 false /* expect_created_receive_stream */);
5054}
5055
eladalonf1841382017-06-12 01:16:46 -07005056TEST_F(WebRtcVideoChannelTest, Vp8PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005057 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
5058 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005059}
5060
eladalonf1841382017-06-12 01:16:46 -07005061TEST_F(WebRtcVideoChannelTest, Vp9PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005062 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP9").id,
5063 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005064}
5065
eladalonf1841382017-06-12 01:16:46 -07005066TEST_F(WebRtcVideoChannelTest, RtxPacketDoesntCreateUnsignalledStream) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02005067 AssignDefaultAptRtxTypes();
magjed509e4fe2016-11-18 01:34:11 -08005068 const cricket::VideoCodec vp8 = GetEngineCodec("VP8");
5069 const int rtx_vp8_payload_type = default_apt_rtx_types_[vp8.id];
5070 TestReceiveUnsignaledSsrcPacket(rtx_vp8_payload_type,
5071 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005072}
5073
eladalonf1841382017-06-12 01:16:46 -07005074TEST_F(WebRtcVideoChannelTest, UlpfecPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005075 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("ulpfec").id,
5076 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005077}
5078
eladalonf1841382017-06-12 01:16:46 -07005079TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr468da7c2016-11-22 02:16:47 -08005080 FlexfecPacketDoesntCreateUnsignalledStream) {
5081 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("flexfec-03").id,
5082 false /* expect_created_receive_stream */);
5083}
5084
eladalonf1841382017-06-12 01:16:46 -07005085TEST_F(WebRtcVideoChannelTest, RedRtxPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005086 TestReceiveUnsignaledSsrcPacket(kRedRtxPayloadType,
5087 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005088}
5089
mzanaty8a855d62017-02-17 15:46:43 -08005090// Test that receiving any unsignalled SSRC works even if it changes.
5091// The first unsignalled SSRC received will create a default receive stream.
5092// Any different unsignalled SSRC received will replace the default.
eladalonf1841382017-06-12 01:16:46 -07005093TEST_F(WebRtcVideoChannelTest, ReceiveDifferentUnsignaledSsrc) {
mzanaty8a855d62017-02-17 15:46:43 -08005094 // Allow receiving VP8, VP9, H264 (if enabled).
5095 cricket::VideoRecvParameters parameters;
5096 parameters.codecs.push_back(GetEngineCodec("VP8"));
5097 parameters.codecs.push_back(GetEngineCodec("VP9"));
5098
5099#if defined(WEBRTC_USE_H264)
5100 cricket::VideoCodec H264codec(126, "H264");
5101 parameters.codecs.push_back(H264codec);
5102#endif
5103
5104 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
5105 // No receive streams yet.
5106 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5107 cricket::FakeVideoRenderer renderer;
5108 EXPECT_TRUE(channel_->SetSink(kDefaultRecvSsrc, &renderer));
5109
5110 // Receive VP8 packet on first SSRC.
5111 uint8_t data[kMinRtpPacketLen];
5112 cricket::RtpHeader rtpHeader;
5113 rtpHeader.payload_type = GetEngineCodec("VP8").id;
5114 rtpHeader.seq_num = rtpHeader.timestamp = 0;
Yves Gerey665174f2018-06-19 15:03:05 +02005115 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 1;
mzanaty8a855d62017-02-17 15:46:43 -08005116 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
5117 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Niels Möllere6933812018-11-05 13:01:41 +01005118 channel_->OnPacketReceived(&packet, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08005119 // VP8 packet should create default receive stream.
5120 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02005121 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
mzanaty8a855d62017-02-17 15:46:43 -08005122 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
5123 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01005124 webrtc::VideoFrame video_frame =
5125 webrtc::VideoFrame::Builder()
5126 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
5127 .set_timestamp_rtp(100)
5128 .set_timestamp_us(0)
5129 .set_rotation(webrtc::kVideoRotation_0)
5130 .build();
mzanaty8a855d62017-02-17 15:46:43 -08005131 recv_stream->InjectFrame(video_frame);
5132 EXPECT_EQ(1, renderer.num_rendered_frames());
5133
5134 // Receive VP9 packet on second SSRC.
5135 rtpHeader.payload_type = GetEngineCodec("VP9").id;
Yves Gerey665174f2018-06-19 15:03:05 +02005136 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 2;
mzanaty8a855d62017-02-17 15:46:43 -08005137 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
5138 rtc::CopyOnWriteBuffer packet2(data, sizeof(data));
Niels Möllere6933812018-11-05 13:01:41 +01005139 channel_->OnPacketReceived(&packet2, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08005140 // VP9 packet should replace the default receive SSRC.
5141 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5142 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
5143 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
5144 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01005145 webrtc::VideoFrame video_frame2 =
5146 webrtc::VideoFrame::Builder()
5147 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
5148 .set_timestamp_rtp(200)
5149 .set_timestamp_us(0)
5150 .set_rotation(webrtc::kVideoRotation_0)
5151 .build();
mzanaty8a855d62017-02-17 15:46:43 -08005152 recv_stream->InjectFrame(video_frame2);
5153 EXPECT_EQ(2, renderer.num_rendered_frames());
5154
5155#if defined(WEBRTC_USE_H264)
5156 // Receive H264 packet on third SSRC.
5157 rtpHeader.payload_type = 126;
Yves Gerey665174f2018-06-19 15:03:05 +02005158 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 3;
mzanaty8a855d62017-02-17 15:46:43 -08005159 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
5160 rtc::CopyOnWriteBuffer packet3(data, sizeof(data));
Niels Möllere6933812018-11-05 13:01:41 +01005161 channel_->OnPacketReceived(&packet3, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08005162 // H264 packet should replace the default receive SSRC.
5163 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5164 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
5165 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
5166 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01005167 webrtc::VideoFrame video_frame3 =
5168 webrtc::VideoFrame::Builder()
5169 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
5170 .set_timestamp_rtp(300)
5171 .set_timestamp_us(0)
5172 .set_rotation(webrtc::kVideoRotation_0)
5173 .build();
mzanaty8a855d62017-02-17 15:46:43 -08005174 recv_stream->InjectFrame(video_frame3);
5175 EXPECT_EQ(3, renderer.num_rendered_frames());
5176#endif
5177}
5178
brandtr0dc57ea2017-05-29 23:33:31 -07005179// This test verifies that when a new default stream is created for a new
5180// unsignaled SSRC, the new stream does not overwrite any old stream that had
5181// been the default receive stream before being properly signaled.
eladalonf1841382017-06-12 01:16:46 -07005182TEST_F(WebRtcVideoChannelTest,
brandtr0dc57ea2017-05-29 23:33:31 -07005183 NewUnsignaledStreamDoesNotDestroyPreviouslyUnsignaledStream) {
5184 cricket::VideoRecvParameters parameters;
5185 parameters.codecs.push_back(GetEngineCodec("VP8"));
5186 ASSERT_TRUE(channel_->SetRecvParameters(parameters));
5187
5188 // No streams signaled and no packets received, so we should not have any
5189 // stream objects created yet.
5190 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5191
5192 // Receive packet on an unsignaled SSRC.
5193 uint8_t data[kMinRtpPacketLen];
5194 cricket::RtpHeader rtp_header;
5195 rtp_header.payload_type = GetEngineCodec("VP8").id;
5196 rtp_header.seq_num = rtp_header.timestamp = 0;
5197 rtp_header.ssrc = kSsrcs3[0];
5198 cricket::SetRtpHeader(data, sizeof(data), rtp_header);
5199 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Niels Möllere6933812018-11-05 13:01:41 +01005200 channel_->OnPacketReceived(&packet, /* packet_time_us */ -1);
brandtr0dc57ea2017-05-29 23:33:31 -07005201 // Default receive stream should be created.
5202 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5203 FakeVideoReceiveStream* recv_stream0 =
5204 fake_call_->GetVideoReceiveStreams()[0];
5205 EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);
5206
5207 // Signal the SSRC.
5208 EXPECT_TRUE(
5209 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs3[0])));
5210 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5211 recv_stream0 = fake_call_->GetVideoReceiveStreams()[0];
5212 EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);
5213
5214 // Receive packet on a different unsignaled SSRC.
5215 rtp_header.ssrc = kSsrcs3[1];
5216 cricket::SetRtpHeader(data, sizeof(data), rtp_header);
5217 packet.SetData(data, sizeof(data));
Niels Möllere6933812018-11-05 13:01:41 +01005218 channel_->OnPacketReceived(&packet, /* packet_time_us */ -1);
brandtr0dc57ea2017-05-29 23:33:31 -07005219 // New default receive stream should be created, but old stream should remain.
5220 ASSERT_EQ(2u, fake_call_->GetVideoReceiveStreams().size());
5221 EXPECT_EQ(recv_stream0, fake_call_->GetVideoReceiveStreams()[0]);
5222 FakeVideoReceiveStream* recv_stream1 =
5223 fake_call_->GetVideoReceiveStreams()[1];
5224 EXPECT_EQ(kSsrcs3[1], recv_stream1->GetConfig().rtp.remote_ssrc);
5225}
5226
Seth Hampson7c682e02018-05-04 16:28:15 -07005227TEST_F(WebRtcVideoChannelTest, CanSetMaxBitrateForExistingStream) {
skvladdc1c62c2016-03-16 19:07:43 -07005228 AddSendStream();
5229
Niels Möller805a27e2019-01-21 12:21:27 +01005230 webrtc::test::FrameForwarder frame_forwarder;
5231 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
skvladdc1c62c2016-03-16 19:07:43 -07005232 EXPECT_TRUE(channel_->SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01005233 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
skvladdc1c62c2016-03-16 19:07:43 -07005234
perkjfa10b552016-10-02 23:45:26 -07005235 int default_encoder_bitrate = GetMaxEncoderBitrate();
brandtr468da7c2016-11-22 02:16:47 -08005236 EXPECT_GT(default_encoder_bitrate, 1000);
skvladdc1c62c2016-03-16 19:07:43 -07005237
5238 // TODO(skvlad): Resolve the inconsistency between the interpretation
5239 // of the global bitrate limit for audio and video:
5240 // - Audio: max_bandwidth_bps = 0 - fail the operation,
5241 // max_bandwidth_bps = -1 - remove the bandwidth limit
5242 // - Video: max_bandwidth_bps = 0 - remove the bandwidth limit,
pbos5c7760a2017-03-10 11:23:12 -08005243 // max_bandwidth_bps = -1 - remove the bandwidth limit
skvladdc1c62c2016-03-16 19:07:43 -07005244
perkjfa10b552016-10-02 23:45:26 -07005245 SetAndExpectMaxBitrate(1000, 0, 1000);
5246 SetAndExpectMaxBitrate(1000, 800, 800);
5247 SetAndExpectMaxBitrate(600, 800, 600);
5248 SetAndExpectMaxBitrate(0, 800, 800);
5249 SetAndExpectMaxBitrate(0, 0, default_encoder_bitrate);
skvladdc1c62c2016-03-16 19:07:43 -07005250
Niels Möllerff40b142018-04-09 08:49:14 +02005251 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
skvladdc1c62c2016-03-16 19:07:43 -07005252}
5253
eladalonf1841382017-06-12 01:16:46 -07005254TEST_F(WebRtcVideoChannelTest, CannotSetMaxBitrateForNonexistentStream) {
skvladdc1c62c2016-03-16 19:07:43 -07005255 webrtc::RtpParameters nonexistent_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005256 channel_->GetRtpSendParameters(last_ssrc_);
Mirko Bonadeif859e552018-05-30 15:31:29 +02005257 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvladdc1c62c2016-03-16 19:07:43 -07005258
5259 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005260 EXPECT_FALSE(
Zach Steinba37b4b2018-01-23 15:02:36 -08005261 channel_->SetRtpSendParameters(last_ssrc_, nonexistent_parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07005262}
5263
eladalonf1841382017-06-12 01:16:46 -07005264TEST_F(WebRtcVideoChannelTest,
Seth Hampson7c682e02018-05-04 16:28:15 -07005265 SetLowMaxBitrateOverwritesVideoStreamMinBitrate) {
Åsa Perssonbdee46d2018-06-25 11:28:06 +02005266 FakeVideoSendStream* stream = AddSendStream();
5267
Seth Hampson7c682e02018-05-04 16:28:15 -07005268 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5269 EXPECT_EQ(1UL, parameters.encodings.size());
5270 EXPECT_FALSE(parameters.encodings[0].max_bitrate_bps.has_value());
5271 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5272
5273 // Note that this is testing the behavior of the FakeVideoSendStream, which
5274 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5275 // we are just testing the behavior of
5276 // EncoderStreamFactory::CreateEncoderStreams.
Åsa Perssonbdee46d2018-06-25 11:28:06 +02005277 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5278 EXPECT_EQ(kMinVideoBitrateBps, stream->GetVideoStreams()[0].min_bitrate_bps);
Seth Hampson7c682e02018-05-04 16:28:15 -07005279
5280 // Set a low max bitrate & check that VideoStream.min_bitrate_bps is limited
5281 // by this amount.
5282 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5283 int low_max_bitrate_bps = kMinVideoBitrateBps - 1000;
5284 parameters.encodings[0].max_bitrate_bps = low_max_bitrate_bps;
5285 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5286
Åsa Perssonbdee46d2018-06-25 11:28:06 +02005287 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5288 EXPECT_EQ(low_max_bitrate_bps, stream->GetVideoStreams()[0].min_bitrate_bps);
5289 EXPECT_EQ(low_max_bitrate_bps, stream->GetVideoStreams()[0].max_bitrate_bps);
5290}
5291
5292TEST_F(WebRtcVideoChannelTest,
5293 SetHighMinBitrateOverwritesVideoStreamMaxBitrate) {
5294 FakeVideoSendStream* stream = AddSendStream();
5295
5296 // Note that this is testing the behavior of the FakeVideoSendStream, which
5297 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5298 // we are just testing the behavior of
5299 // EncoderStreamFactory::CreateEncoderStreams.
5300 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5301 int high_min_bitrate_bps = stream->GetVideoStreams()[0].max_bitrate_bps + 1;
5302
5303 // Set a high min bitrate and check that max_bitrate_bps is adjusted up.
5304 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5305 EXPECT_EQ(1UL, parameters.encodings.size());
5306 parameters.encodings[0].min_bitrate_bps = high_min_bitrate_bps;
5307 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5308
5309 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5310 EXPECT_EQ(high_min_bitrate_bps, stream->GetVideoStreams()[0].min_bitrate_bps);
5311 EXPECT_EQ(high_min_bitrate_bps, stream->GetVideoStreams()[0].max_bitrate_bps);
5312}
5313
5314TEST_F(WebRtcVideoChannelTest,
5315 SetMinBitrateAboveMaxBitrateLimitAdjustsMinBitrateDown) {
5316 send_parameters_.max_bandwidth_bps = 99999;
5317 FakeVideoSendStream* stream = AddSendStream();
5318 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
5319 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
5320 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5321 EXPECT_EQ(kMinVideoBitrateBps, stream->GetVideoStreams()[0].min_bitrate_bps);
5322 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
5323 stream->GetVideoStreams()[0].max_bitrate_bps);
5324
5325 // Set min bitrate above global max bitrate and check that min_bitrate_bps is
5326 // adjusted down.
5327 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5328 EXPECT_EQ(1UL, parameters.encodings.size());
5329 parameters.encodings[0].min_bitrate_bps = 99999 + 1;
5330 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5331 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5332 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
5333 stream->GetVideoStreams()[0].min_bitrate_bps);
5334 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
5335 stream->GetVideoStreams()[0].max_bitrate_bps);
Seth Hampson7c682e02018-05-04 16:28:15 -07005336}
5337
Åsa Persson8c1bf952018-09-13 10:42:19 +02005338TEST_F(WebRtcVideoChannelTest, SetMaxFramerateOneStream) {
5339 FakeVideoSendStream* stream = AddSendStream();
5340
5341 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5342 EXPECT_EQ(1UL, parameters.encodings.size());
5343 EXPECT_FALSE(parameters.encodings[0].max_framerate.has_value());
5344 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5345
5346 // Note that this is testing the behavior of the FakeVideoSendStream, which
5347 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5348 // we are just testing the behavior of
5349 // EncoderStreamFactory::CreateEncoderStreams.
5350 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5351 EXPECT_EQ(kDefaultVideoMaxFramerate,
5352 stream->GetVideoStreams()[0].max_framerate);
5353
5354 // Set max framerate and check that VideoStream.max_framerate is set.
5355 const int kNewMaxFramerate = kDefaultVideoMaxFramerate - 1;
5356 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5357 parameters.encodings[0].max_framerate = kNewMaxFramerate;
5358 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5359
5360 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5361 EXPECT_EQ(kNewMaxFramerate, stream->GetVideoStreams()[0].max_framerate);
5362}
5363
Åsa Persson23eba222018-10-02 14:47:06 +02005364TEST_F(WebRtcVideoChannelTest, SetNumTemporalLayersForSingleStream) {
5365 FakeVideoSendStream* stream = AddSendStream();
5366
5367 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5368 EXPECT_EQ(1UL, parameters.encodings.size());
5369 EXPECT_FALSE(parameters.encodings[0].num_temporal_layers.has_value());
5370 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5371
5372 // Note that this is testing the behavior of the FakeVideoSendStream, which
5373 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5374 // we are just testing the behavior of
5375 // EncoderStreamFactory::CreateEncoderStreams.
5376 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5377 EXPECT_FALSE(stream->GetVideoStreams()[0].num_temporal_layers.has_value());
5378
5379 // Set temporal layers and check that VideoStream.num_temporal_layers is set.
5380 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5381 parameters.encodings[0].num_temporal_layers = 2;
5382 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5383
5384 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5385 EXPECT_EQ(2UL, stream->GetVideoStreams()[0].num_temporal_layers);
5386}
5387
Seth Hampson7c682e02018-05-04 16:28:15 -07005388TEST_F(WebRtcVideoChannelTest,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005389 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvladdc1c62c2016-03-16 19:07:43 -07005390 AddSendStream();
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005391 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07005392 // Two or more encodings should result in failure.
5393 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08005394 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08005395 // Zero encodings should also fail.
5396 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08005397 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08005398}
5399
Zach Stein3ca452b2018-01-18 10:01:24 -08005400TEST_F(WebRtcVideoChannelTest,
5401 CannotSetSimulcastRtpSendParametersWithIncorrectNumberOfEncodings) {
5402 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
5403 StreamParams sp = CreateSimStreamParams("cname", ssrcs);
5404 AddSendStream(sp);
5405
5406 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5407
5408 // Additional encodings should result in failure.
5409 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08005410 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Zach Stein3ca452b2018-01-18 10:01:24 -08005411 // Zero encodings should also fail.
5412 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08005413 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Zach Stein3ca452b2018-01-18 10:01:24 -08005414}
5415
deadbeeffb2aced2017-01-06 23:05:37 -08005416// Changing the SSRC through RtpParameters is not allowed.
eladalonf1841382017-06-12 01:16:46 -07005417TEST_F(WebRtcVideoChannelTest, CannotSetSsrcInRtpSendParameters) {
deadbeeffb2aced2017-01-06 23:05:37 -08005418 AddSendStream();
5419 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
Oskar Sundbom78807582017-11-16 11:09:55 +01005420 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08005421 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07005422}
5423
Seth Hampson24722b32017-12-22 09:36:42 -08005424// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
5425// a value <= 0, setting the parameters returns false.
5426TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersInvalidBitratePriority) {
5427 AddSendStream();
5428 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5429 EXPECT_EQ(1UL, parameters.encodings.size());
5430 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5431 parameters.encodings[0].bitrate_priority);
5432
5433 parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08005434 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005435 parameters.encodings[0].bitrate_priority = -2;
Zach Steinba37b4b2018-01-23 15:02:36 -08005436 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005437}
5438
5439// Tests when the the RTCRtpEncodingParameters.bitrate_priority gets set
5440// properly on the VideoChannel and propogates down to the video encoder.
5441TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersPriorityOneStream) {
5442 AddSendStream();
5443 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5444 EXPECT_EQ(1UL, parameters.encodings.size());
5445 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5446 parameters.encodings[0].bitrate_priority);
5447
5448 // Change the value and set it on the VideoChannel.
5449 double new_bitrate_priority = 2.0;
5450 parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08005451 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005452
5453 // Verify that the encoding parameters bitrate_priority is set for the
5454 // VideoChannel.
5455 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5456 EXPECT_EQ(1UL, parameters.encodings.size());
5457 EXPECT_EQ(new_bitrate_priority, parameters.encodings[0].bitrate_priority);
5458
5459 // Verify that the new value propagated down to the encoder.
5460 std::vector<FakeVideoSendStream*> video_send_streams =
5461 fake_call_->GetVideoSendStreams();
5462 EXPECT_EQ(1UL, video_send_streams.size());
5463 FakeVideoSendStream* video_send_stream = video_send_streams.front();
5464 // Check that the WebRtcVideoSendStream updated the VideoEncoderConfig
5465 // appropriately.
5466 EXPECT_EQ(new_bitrate_priority,
5467 video_send_stream->GetEncoderConfig().bitrate_priority);
5468 // Check that the vector of VideoStreams also was propagated correctly. Note
5469 // that this is testing the behavior of the FakeVideoSendStream, which mimics
5470 // the calls to CreateEncoderStreams to get the VideoStreams.
Danil Chapovalov00c71832018-06-15 15:58:38 +02005471 EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
Seth Hampson24722b32017-12-22 09:36:42 -08005472 video_send_stream->GetVideoStreams()[0].bitrate_priority);
5473}
5474
5475// Tests that the RTCRtpEncodingParameters.bitrate_priority is set for the
5476// VideoChannel and the value propogates to the video encoder with all simulcast
5477// streams.
5478TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersPrioritySimulcastStreams) {
5479 // Create the stream params with multiple ssrcs for simulcast.
Åsa Persson31cb8f92018-06-27 10:44:56 +02005480 const size_t kNumSimulcastStreams = 3;
Seth Hampson24722b32017-12-22 09:36:42 -08005481 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
5482 StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
5483 AddSendStream(stream_params);
5484 uint32_t primary_ssrc = stream_params.first_ssrc();
5485
Niels Möller805a27e2019-01-21 12:21:27 +01005486 // Using the FrameForwarder, we manually send a full size
Tommi85959932018-02-07 19:26:06 +01005487 // frame. This creates multiple VideoStreams for all simulcast layers when
5488 // reconfiguring, and allows us to test this behavior.
Niels Möller805a27e2019-01-21 12:21:27 +01005489 webrtc::test::FrameForwarder frame_forwarder;
Seth Hampson24722b32017-12-22 09:36:42 -08005490 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01005491 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
Seth Hampson24722b32017-12-22 09:36:42 -08005492 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01005493 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
5494 1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
5495 rtc::kNumMicrosecsPerSec / 30));
5496
Seth Hampson24722b32017-12-22 09:36:42 -08005497 // Get and set the rtp encoding parameters.
5498 webrtc::RtpParameters parameters =
5499 channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02005500 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson24722b32017-12-22 09:36:42 -08005501 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5502 parameters.encodings[0].bitrate_priority);
5503 // Change the value and set it on the VideoChannel.
5504 double new_bitrate_priority = 2.0;
5505 parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08005506 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005507
5508 // Verify that the encoding parameters priority is set on the VideoChannel.
5509 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02005510 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson24722b32017-12-22 09:36:42 -08005511 EXPECT_EQ(new_bitrate_priority, parameters.encodings[0].bitrate_priority);
5512
5513 // Verify that the new value propagated down to the encoder.
5514 std::vector<FakeVideoSendStream*> video_send_streams =
5515 fake_call_->GetVideoSendStreams();
5516 EXPECT_EQ(1UL, video_send_streams.size());
5517 FakeVideoSendStream* video_send_stream = video_send_streams.front();
5518 // Check that the WebRtcVideoSendStream updated the VideoEncoderConfig
5519 // appropriately.
Åsa Persson31cb8f92018-06-27 10:44:56 +02005520 EXPECT_EQ(kNumSimulcastStreams,
Seth Hampson24722b32017-12-22 09:36:42 -08005521 video_send_stream->GetEncoderConfig().number_of_streams);
5522 EXPECT_EQ(new_bitrate_priority,
5523 video_send_stream->GetEncoderConfig().bitrate_priority);
5524 // Check that the vector of VideoStreams also propagated correctly. The
5525 // FakeVideoSendStream calls CreateEncoderStreams, and we are testing that
5526 // these are created appropriately for the simulcast case.
Åsa Persson31cb8f92018-06-27 10:44:56 +02005527 EXPECT_EQ(kNumSimulcastStreams, video_send_stream->GetVideoStreams().size());
Danil Chapovalov00c71832018-06-15 15:58:38 +02005528 EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
Seth Hampson24722b32017-12-22 09:36:42 -08005529 video_send_stream->GetVideoStreams()[0].bitrate_priority);
5530 // Since we are only setting bitrate priority per-sender, the other
5531 // VideoStreams should have a bitrate priority of 0.
Danil Chapovalov00c71832018-06-15 15:58:38 +02005532 EXPECT_EQ(absl::nullopt,
Seth Hampson24722b32017-12-22 09:36:42 -08005533 video_send_stream->GetVideoStreams()[1].bitrate_priority);
Danil Chapovalov00c71832018-06-15 15:58:38 +02005534 EXPECT_EQ(absl::nullopt,
Seth Hampson24722b32017-12-22 09:36:42 -08005535 video_send_stream->GetVideoStreams()[2].bitrate_priority);
Niels Möllerff40b142018-04-09 08:49:14 +02005536 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
Seth Hampson24722b32017-12-22 09:36:42 -08005537}
5538
Tim Haloun648d28a2018-10-18 16:52:22 -07005539// RTCRtpEncodingParameters.network_priority must be one of a few values
5540// derived from the default priority, corresponding to very-low, low, medium,
5541// or high.
5542TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersInvalidNetworkPriority) {
5543 AddSendStream();
5544 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5545 EXPECT_EQ(1UL, parameters.encodings.size());
5546 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5547 parameters.encodings[0].network_priority);
5548
5549 double good_values[] = {0.5, 1.0, 2.0, 4.0};
5550 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
5551 for (auto it : good_values) {
5552 parameters.encodings[0].network_priority = it;
5553 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5554 }
5555 for (auto it : bad_values) {
5556 parameters.encodings[0].network_priority = it;
5557 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5558 }
5559}
5560
Åsa Persson8c1bf952018-09-13 10:42:19 +02005561TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersMaxFramerate) {
5562 const size_t kNumSimulcastStreams = 3;
5563 SetUpSimulcast(true, false);
5564
5565 // Get and set the rtp encoding parameters.
5566 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5567 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5568 for (const auto& encoding : parameters.encodings) {
5569 EXPECT_FALSE(encoding.max_framerate);
5570 }
5571
5572 // Change the value and set it on the VideoChannel.
5573 parameters.encodings[0].max_framerate = 10;
5574 parameters.encodings[1].max_framerate = 20;
5575 parameters.encodings[2].max_framerate = 25;
5576 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5577
5578 // Verify that the bitrates are set on the VideoChannel.
5579 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5580 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5581 EXPECT_EQ(10, parameters.encodings[0].max_framerate);
5582 EXPECT_EQ(20, parameters.encodings[1].max_framerate);
5583 EXPECT_EQ(25, parameters.encodings[2].max_framerate);
5584}
5585
Åsa Persson23eba222018-10-02 14:47:06 +02005586TEST_F(WebRtcVideoChannelTest,
5587 SetRtpSendParametersNumTemporalLayersFailsForInvalidRange) {
5588 const size_t kNumSimulcastStreams = 3;
5589 SetUpSimulcast(true, false);
5590
5591 // Get and set the rtp encoding parameters.
5592 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5593 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5594
5595 // Num temporal layers should be in the range [1, kMaxTemporalStreams].
5596 parameters.encodings[0].num_temporal_layers = 0;
5597 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
5598 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
5599 parameters.encodings[0].num_temporal_layers = webrtc::kMaxTemporalStreams + 1;
5600 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
5601 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
5602}
5603
5604TEST_F(WebRtcVideoChannelTest,
5605 SetRtpSendParametersNumTemporalLayersFailsForInvalidModification) {
5606 const size_t kNumSimulcastStreams = 3;
5607 SetUpSimulcast(true, false);
5608
5609 // Get and set the rtp encoding parameters.
5610 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5611 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5612
5613 // No/all layers should be set.
5614 parameters.encodings[0].num_temporal_layers = 1;
5615 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION,
5616 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
5617
5618 // Different values not supported.
5619 parameters.encodings[0].num_temporal_layers = 1;
5620 parameters.encodings[1].num_temporal_layers = 2;
5621 parameters.encodings[2].num_temporal_layers = 2;
5622 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION,
5623 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
5624}
5625
5626TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersNumTemporalLayers) {
5627 const size_t kNumSimulcastStreams = 3;
5628 SetUpSimulcast(true, false);
5629
5630 // Get and set the rtp encoding parameters.
5631 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5632 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5633 for (const auto& encoding : parameters.encodings)
5634 EXPECT_FALSE(encoding.num_temporal_layers);
5635
5636 // Change the value and set it on the VideoChannel.
5637 parameters.encodings[0].num_temporal_layers = 3;
5638 parameters.encodings[1].num_temporal_layers = 3;
5639 parameters.encodings[2].num_temporal_layers = 3;
5640 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5641
5642 // Verify that the number of temporal layers are set on the VideoChannel.
5643 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5644 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5645 EXPECT_EQ(3, parameters.encodings[0].num_temporal_layers);
5646 EXPECT_EQ(3, parameters.encodings[1].num_temporal_layers);
5647 EXPECT_EQ(3, parameters.encodings[2].num_temporal_layers);
5648}
5649
5650TEST_F(WebRtcVideoChannelTest, NumTemporalLayersPropagatedToEncoder) {
5651 const size_t kNumSimulcastStreams = 3;
5652 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5653
5654 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01005655 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson23eba222018-10-02 14:47:06 +02005656 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01005657 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson23eba222018-10-02 14:47:06 +02005658 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01005659 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson23eba222018-10-02 14:47:06 +02005660
5661 // Get and set the rtp encoding parameters.
5662 // Change the value and set it on the VideoChannel.
5663 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5664 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5665 parameters.encodings[0].num_temporal_layers = 2;
5666 parameters.encodings[1].num_temporal_layers = 2;
5667 parameters.encodings[2].num_temporal_layers = 2;
5668 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5669
5670 // Verify that the new value is propagated down to the encoder.
5671 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
5672 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
5673 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
5674 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
5675 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
5676 EXPECT_EQ(2UL, encoder_config.simulcast_layers[0].num_temporal_layers);
5677 EXPECT_EQ(2UL, encoder_config.simulcast_layers[1].num_temporal_layers);
5678 EXPECT_EQ(2UL, encoder_config.simulcast_layers[2].num_temporal_layers);
5679
5680 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
5681 // VideoStreams are created appropriately for the simulcast case.
5682 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
5683 EXPECT_EQ(2UL, stream->GetVideoStreams()[0].num_temporal_layers);
5684 EXPECT_EQ(2UL, stream->GetVideoStreams()[1].num_temporal_layers);
5685 EXPECT_EQ(2UL, stream->GetVideoStreams()[2].num_temporal_layers);
5686
5687 // No parameter changed, encoder should not be reconfigured.
5688 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5689 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
5690
5691 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
5692}
5693
5694TEST_F(WebRtcVideoChannelTest,
5695 DefaultValuePropagatedToEncoderForUnsetNumTemporalLayers) {
5696 const size_t kDefaultNumTemporalLayers = 3;
5697 const size_t kNumSimulcastStreams = 3;
5698 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5699
5700 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01005701 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson23eba222018-10-02 14:47:06 +02005702 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01005703 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson23eba222018-10-02 14:47:06 +02005704 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01005705 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson23eba222018-10-02 14:47:06 +02005706
5707 // Change rtp encoding parameters, num_temporal_layers not changed.
5708 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5709 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5710 parameters.encodings[0].min_bitrate_bps = 33000;
5711 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5712
5713 // Verify that no value is propagated down to the encoder.
5714 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
5715 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
5716 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
5717 EXPECT_FALSE(encoder_config.simulcast_layers[0].num_temporal_layers);
5718 EXPECT_FALSE(encoder_config.simulcast_layers[1].num_temporal_layers);
5719 EXPECT_FALSE(encoder_config.simulcast_layers[2].num_temporal_layers);
5720
5721 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
5722 // VideoStreams are created appropriately for the simulcast case.
5723 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
5724 EXPECT_EQ(kDefaultNumTemporalLayers,
5725 stream->GetVideoStreams()[0].num_temporal_layers);
5726 EXPECT_EQ(kDefaultNumTemporalLayers,
5727 stream->GetVideoStreams()[1].num_temporal_layers);
5728 EXPECT_EQ(kDefaultNumTemporalLayers,
5729 stream->GetVideoStreams()[2].num_temporal_layers);
5730
5731 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
5732}
5733
Åsa Persson8c1bf952018-09-13 10:42:19 +02005734TEST_F(WebRtcVideoChannelTest, MaxSimulcastFrameratePropagatedToEncoder) {
5735 const size_t kNumSimulcastStreams = 3;
5736 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5737
5738 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01005739 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson8c1bf952018-09-13 10:42:19 +02005740 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01005741 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson8c1bf952018-09-13 10:42:19 +02005742 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01005743 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson8c1bf952018-09-13 10:42:19 +02005744
5745 // Get and set the rtp encoding parameters.
5746 // Change the value and set it on the VideoChannel.
5747 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5748 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5749 parameters.encodings[0].max_framerate = 15;
5750 parameters.encodings[1].max_framerate = 25;
5751 parameters.encodings[2].max_framerate = 20;
5752 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5753
5754 // Verify that the new value propagated down to the encoder.
5755 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
5756 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
5757 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
5758 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
5759 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
5760 EXPECT_EQ(15, encoder_config.simulcast_layers[0].max_framerate);
5761 EXPECT_EQ(25, encoder_config.simulcast_layers[1].max_framerate);
5762 EXPECT_EQ(20, encoder_config.simulcast_layers[2].max_framerate);
5763
5764 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
5765 // VideoStreams are created appropriately for the simulcast case.
5766 // Currently the maximum |max_framerate| is used.
5767 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
5768 EXPECT_EQ(25, stream->GetVideoStreams()[0].max_framerate);
5769 EXPECT_EQ(25, stream->GetVideoStreams()[1].max_framerate);
5770 EXPECT_EQ(25, stream->GetVideoStreams()[2].max_framerate);
5771
5772 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
5773}
5774
5775TEST_F(WebRtcVideoChannelTest,
5776 DefaultValuePropagatedToEncoderForUnsetFramerate) {
5777 const size_t kNumSimulcastStreams = 3;
5778 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
5779 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5780
5781 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01005782 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson8c1bf952018-09-13 10:42:19 +02005783 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01005784 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson8c1bf952018-09-13 10:42:19 +02005785 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01005786 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson8c1bf952018-09-13 10:42:19 +02005787
5788 // Get and set the rtp encoding parameters.
5789 // Change the value and set it on the VideoChannel.
5790 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5791 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5792 parameters.encodings[0].max_framerate = 15;
5793 parameters.encodings[2].max_framerate = 20;
5794 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5795
5796 // Verify that the new value propagated down to the encoder.
5797 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
5798 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
5799 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
5800 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
5801 EXPECT_EQ(15, encoder_config.simulcast_layers[0].max_framerate);
5802 EXPECT_EQ(-1, encoder_config.simulcast_layers[1].max_framerate);
5803 EXPECT_EQ(20, encoder_config.simulcast_layers[2].max_framerate);
5804
5805 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
5806 // VideoStreams are created appropriately for the simulcast case.
5807 // The maximum |max_framerate| is used, kDefaultVideoMaxFramerate: 60.
5808 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
5809 EXPECT_EQ(kDefaultVideoMaxFramerate,
5810 stream->GetVideoStreams()[0].max_framerate);
5811 EXPECT_EQ(kDefaultVideoMaxFramerate,
5812 stream->GetVideoStreams()[1].max_framerate);
5813 EXPECT_EQ(kDefaultVideoMaxFramerate,
5814 stream->GetVideoStreams()[2].max_framerate);
5815
5816 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
5817}
5818
Åsa Persson55659812018-06-18 17:51:32 +02005819TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersMinAndMaxBitrate) {
5820 const size_t kNumSimulcastStreams = 3;
5821 SetUpSimulcast(true, false);
5822
5823 // Get and set the rtp encoding parameters.
5824 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5825 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5826 for (const auto& encoding : parameters.encodings) {
5827 EXPECT_FALSE(encoding.min_bitrate_bps);
5828 EXPECT_FALSE(encoding.max_bitrate_bps);
5829 }
5830
5831 // Change the value and set it on the VideoChannel.
5832 parameters.encodings[0].min_bitrate_bps = 100000;
5833 parameters.encodings[0].max_bitrate_bps = 200000;
5834 parameters.encodings[1].min_bitrate_bps = 300000;
5835 parameters.encodings[1].max_bitrate_bps = 400000;
5836 parameters.encodings[2].min_bitrate_bps = 500000;
5837 parameters.encodings[2].max_bitrate_bps = 600000;
5838 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5839
5840 // Verify that the bitrates are set on the VideoChannel.
5841 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5842 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5843 EXPECT_EQ(100000, parameters.encodings[0].min_bitrate_bps);
5844 EXPECT_EQ(200000, parameters.encodings[0].max_bitrate_bps);
5845 EXPECT_EQ(300000, parameters.encodings[1].min_bitrate_bps);
5846 EXPECT_EQ(400000, parameters.encodings[1].max_bitrate_bps);
5847 EXPECT_EQ(500000, parameters.encodings[2].min_bitrate_bps);
5848 EXPECT_EQ(600000, parameters.encodings[2].max_bitrate_bps);
5849}
5850
5851TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersFailsWithIncorrectBitrate) {
5852 const size_t kNumSimulcastStreams = 3;
5853 SetUpSimulcast(true, false);
5854
5855 // Get and set the rtp encoding parameters.
5856 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5857 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5858
5859 // Max bitrate lower than min bitrate should fail.
5860 parameters.encodings[2].min_bitrate_bps = 100000;
5861 parameters.encodings[2].max_bitrate_bps = 100000 - 1;
5862 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
5863 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
5864}
5865
5866// Test that min and max bitrate values set via RtpParameters are correctly
5867// propagated to the underlying encoder, and that the target is set to 3/4 of
5868// the maximum (3/4 was chosen because it's similar to the simulcast defaults
5869// that are used if no min/max are specified).
5870TEST_F(WebRtcVideoChannelTest, MinAndMaxSimulcastBitratePropagatedToEncoder) {
5871 const size_t kNumSimulcastStreams = 3;
5872 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5873
5874 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01005875 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02005876 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01005877 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02005878 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01005879 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02005880
5881 // Get and set the rtp encoding parameters.
5882 // Change the value and set it on the VideoChannel.
5883 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5884 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5885 parameters.encodings[0].min_bitrate_bps = 100000;
5886 parameters.encodings[0].max_bitrate_bps = 200000;
5887 parameters.encodings[1].min_bitrate_bps = 300000;
5888 parameters.encodings[1].max_bitrate_bps = 400000;
5889 parameters.encodings[2].min_bitrate_bps = 500000;
5890 parameters.encodings[2].max_bitrate_bps = 600000;
5891 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5892
5893 // Verify that the new value propagated down to the encoder.
5894 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
5895 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
5896 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
5897 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
5898 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
5899 EXPECT_EQ(100000, encoder_config.simulcast_layers[0].min_bitrate_bps);
5900 EXPECT_EQ(200000, encoder_config.simulcast_layers[0].max_bitrate_bps);
5901 EXPECT_EQ(300000, encoder_config.simulcast_layers[1].min_bitrate_bps);
5902 EXPECT_EQ(400000, encoder_config.simulcast_layers[1].max_bitrate_bps);
5903 EXPECT_EQ(500000, encoder_config.simulcast_layers[2].min_bitrate_bps);
5904 EXPECT_EQ(600000, encoder_config.simulcast_layers[2].max_bitrate_bps);
5905
5906 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
5907 // VideoStreams are created appropriately for the simulcast case.
5908 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
5909 // Target bitrate: 200000 * 3 / 4 = 150000.
5910 EXPECT_EQ(100000, stream->GetVideoStreams()[0].min_bitrate_bps);
5911 EXPECT_EQ(150000, stream->GetVideoStreams()[0].target_bitrate_bps);
5912 EXPECT_EQ(200000, stream->GetVideoStreams()[0].max_bitrate_bps);
5913 // Target bitrate: 400000 * 3 / 4 = 300000.
5914 EXPECT_EQ(300000, stream->GetVideoStreams()[1].min_bitrate_bps);
5915 EXPECT_EQ(300000, stream->GetVideoStreams()[1].target_bitrate_bps);
5916 EXPECT_EQ(400000, stream->GetVideoStreams()[1].max_bitrate_bps);
5917 // Target bitrate: 600000 * 3 / 4 = 450000, less than min -> max.
5918 EXPECT_EQ(500000, stream->GetVideoStreams()[2].min_bitrate_bps);
5919 EXPECT_EQ(600000, stream->GetVideoStreams()[2].target_bitrate_bps);
5920 EXPECT_EQ(600000, stream->GetVideoStreams()[2].max_bitrate_bps);
5921
5922 // No parameter changed, encoder should not be reconfigured.
5923 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5924 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
5925
5926 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
5927}
5928
5929// Test to only specify the min or max bitrate value for a layer via
5930// RtpParameters. The unspecified min/max and target value should be set to the
5931// simulcast default that is used if no min/max are specified.
5932TEST_F(WebRtcVideoChannelTest, MinOrMaxSimulcastBitratePropagatedToEncoder) {
5933 const size_t kNumSimulcastStreams = 3;
5934 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
5935 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5936
5937 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01005938 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02005939 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01005940 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02005941 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01005942 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02005943
5944 // Get and set the rtp encoding parameters.
5945 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5946 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
5947
5948 // Change the value and set it on the VideoChannel.
5949 // Layer 0: only configure min bitrate.
5950 const int kMinBpsLayer0 = kDefault[0].min_bitrate_bps + 1;
5951 parameters.encodings[0].min_bitrate_bps = kMinBpsLayer0;
5952 // Layer 1: only configure max bitrate.
5953 const int kMaxBpsLayer1 = kDefault[1].max_bitrate_bps - 1;
5954 parameters.encodings[1].max_bitrate_bps = kMaxBpsLayer1;
5955 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5956
5957 // Verify that the new value propagated down to the encoder.
5958 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
5959 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
5960 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
5961 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
5962 EXPECT_EQ(kMinBpsLayer0, encoder_config.simulcast_layers[0].min_bitrate_bps);
5963 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].max_bitrate_bps);
5964 EXPECT_EQ(-1, encoder_config.simulcast_layers[1].min_bitrate_bps);
5965 EXPECT_EQ(kMaxBpsLayer1, encoder_config.simulcast_layers[1].max_bitrate_bps);
5966 EXPECT_EQ(-1, encoder_config.simulcast_layers[2].min_bitrate_bps);
5967 EXPECT_EQ(-1, encoder_config.simulcast_layers[2].max_bitrate_bps);
5968
5969 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
5970 // VideoStreams are created appropriately for the simulcast case.
5971 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
5972 // Layer 0: min configured bitrate should overwrite min default.
5973 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].min_bitrate_bps);
5974 EXPECT_EQ(kDefault[0].target_bitrate_bps,
5975 stream->GetVideoStreams()[0].target_bitrate_bps);
5976 EXPECT_EQ(kDefault[0].max_bitrate_bps,
5977 stream->GetVideoStreams()[0].max_bitrate_bps);
5978 // Layer 1: max configured bitrate should overwrite max default.
5979 EXPECT_EQ(kDefault[1].min_bitrate_bps,
5980 stream->GetVideoStreams()[1].min_bitrate_bps);
5981 EXPECT_EQ(kDefault[1].target_bitrate_bps,
5982 stream->GetVideoStreams()[1].target_bitrate_bps);
5983 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].max_bitrate_bps);
5984 // Layer 2: min and max bitrate not configured, default expected.
5985 EXPECT_EQ(kDefault[2].min_bitrate_bps,
5986 stream->GetVideoStreams()[2].min_bitrate_bps);
5987 EXPECT_EQ(kDefault[2].target_bitrate_bps,
5988 stream->GetVideoStreams()[2].target_bitrate_bps);
5989 EXPECT_EQ(kDefault[2].max_bitrate_bps,
5990 stream->GetVideoStreams()[2].max_bitrate_bps);
5991
5992 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
5993}
5994
5995// Test that specifying the min (or max) bitrate value for a layer via
5996// RtpParameters above (or below) the simulcast default max (or min) adjusts the
5997// unspecified values accordingly.
5998TEST_F(WebRtcVideoChannelTest, SetMinAndMaxSimulcastBitrateAboveBelowDefault) {
5999 const size_t kNumSimulcastStreams = 3;
6000 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6001 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6002
6003 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006004 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006005 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006006 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006007 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006008 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006009
6010 // Get and set the rtp encoding parameters.
6011 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6012 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6013
6014 // Change the value and set it on the VideoChannel.
6015 // For layer 0, set the min bitrate above the default max.
6016 const int kMinBpsLayer0 = kDefault[0].max_bitrate_bps + 1;
6017 parameters.encodings[0].min_bitrate_bps = kMinBpsLayer0;
6018 // For layer 1, set the max bitrate below the default min.
6019 const int kMaxBpsLayer1 = kDefault[1].min_bitrate_bps - 1;
6020 parameters.encodings[1].max_bitrate_bps = kMaxBpsLayer1;
6021 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6022
6023 // Verify that the new value propagated down to the encoder.
6024 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6025 // VideoStreams are created appropriately for the simulcast case.
6026 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6027 // Layer 0: Min bitrate above default max (target/max should be adjusted).
6028 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].min_bitrate_bps);
6029 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].target_bitrate_bps);
6030 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].max_bitrate_bps);
6031 // Layer 1: Max bitrate below default min (min/target should be adjusted).
6032 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].min_bitrate_bps);
6033 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].target_bitrate_bps);
6034 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].max_bitrate_bps);
6035 // Layer 2: min and max bitrate not configured, default expected.
6036 EXPECT_EQ(kDefault[2].min_bitrate_bps,
6037 stream->GetVideoStreams()[2].min_bitrate_bps);
6038 EXPECT_EQ(kDefault[2].target_bitrate_bps,
6039 stream->GetVideoStreams()[2].target_bitrate_bps);
6040 EXPECT_EQ(kDefault[2].max_bitrate_bps,
6041 stream->GetVideoStreams()[2].max_bitrate_bps);
6042
6043 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6044}
6045
6046TEST_F(WebRtcVideoChannelTest, BandwidthAboveTotalMaxBitrateGivenToMaxLayer) {
6047 const size_t kNumSimulcastStreams = 3;
6048 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6049 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6050
6051 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006052 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006053 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006054 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006055 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006056 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006057
6058 // Set max bitrate for all but the highest layer.
6059 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6060 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6061 parameters.encodings[0].max_bitrate_bps = kDefault[0].max_bitrate_bps;
6062 parameters.encodings[1].max_bitrate_bps = kDefault[1].max_bitrate_bps;
6063 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6064
6065 // Set max bandwidth equal to total max bitrate.
6066 send_parameters_.max_bandwidth_bps =
6067 GetTotalMaxBitrateBps(stream->GetVideoStreams());
6068 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
6069 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
6070
6071 // No bitrate above the total max to give to the highest layer.
6072 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6073 EXPECT_EQ(kDefault[2].max_bitrate_bps,
6074 stream->GetVideoStreams()[2].max_bitrate_bps);
6075
6076 // Set max bandwidth above the total max bitrate.
6077 send_parameters_.max_bandwidth_bps =
6078 GetTotalMaxBitrateBps(stream->GetVideoStreams()) + 1;
6079 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
6080 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
6081
6082 // The highest layer has no max bitrate set -> the bitrate above the total
6083 // max should be given to the highest layer.
6084 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6085 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
6086 GetTotalMaxBitrateBps(stream->GetVideoStreams()));
6087 EXPECT_EQ(kDefault[2].max_bitrate_bps + 1,
6088 stream->GetVideoStreams()[2].max_bitrate_bps);
6089
6090 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6091}
6092
6093TEST_F(WebRtcVideoChannelTest,
6094 BandwidthAboveTotalMaxBitrateNotGivenToMaxLayerIfMaxBitrateSet) {
6095 const size_t kNumSimulcastStreams = 3;
6096 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6097 EXPECT_EQ(kNumSimulcastStreams, kDefault.size());
6098 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6099
6100 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006101 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006102 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006103 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006104 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006105 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006106
6107 // Set max bitrate for the highest layer.
6108 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6109 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6110 parameters.encodings[2].max_bitrate_bps = kDefault[2].max_bitrate_bps;
6111 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6112
6113 // Set max bandwidth above the total max bitrate.
6114 send_parameters_.max_bandwidth_bps =
6115 GetTotalMaxBitrateBps(stream->GetVideoStreams()) + 1;
6116 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
6117 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
6118
6119 // The highest layer has the max bitrate set -> the bitrate above the total
6120 // max should not be given to the highest layer.
6121 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6122 EXPECT_EQ(*parameters.encodings[2].max_bitrate_bps,
6123 stream->GetVideoStreams()[2].max_bitrate_bps);
6124
6125 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6126}
6127
Åsa Perssonbdee46d2018-06-25 11:28:06 +02006128// Test that min and max bitrate values set via RtpParameters are correctly
6129// propagated to the underlying encoder for a single stream.
6130TEST_F(WebRtcVideoChannelTest, MinAndMaxBitratePropagatedToEncoder) {
6131 FakeVideoSendStream* stream = AddSendStream();
6132 EXPECT_TRUE(channel_->SetSend(true));
6133 EXPECT_TRUE(stream->IsSending());
6134
6135 // Set min and max bitrate.
6136 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6137 EXPECT_EQ(1u, parameters.encodings.size());
6138 parameters.encodings[0].min_bitrate_bps = 80000;
6139 parameters.encodings[0].max_bitrate_bps = 150000;
6140 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6141
6142 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6143 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6144 EXPECT_EQ(1u, encoder_config.number_of_streams);
6145 EXPECT_EQ(1u, encoder_config.simulcast_layers.size());
6146 EXPECT_EQ(80000, encoder_config.simulcast_layers[0].min_bitrate_bps);
6147 EXPECT_EQ(150000, encoder_config.simulcast_layers[0].max_bitrate_bps);
6148
6149 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6150 // VideoStreams are created appropriately.
6151 EXPECT_EQ(1u, stream->GetVideoStreams().size());
6152 EXPECT_EQ(80000, stream->GetVideoStreams()[0].min_bitrate_bps);
6153 EXPECT_EQ(150000, stream->GetVideoStreams()[0].target_bitrate_bps);
6154 EXPECT_EQ(150000, stream->GetVideoStreams()[0].max_bitrate_bps);
6155}
6156
6157// Test the default min and max bitrate value are correctly propagated to the
6158// underlying encoder for a single stream (when the values are not set via
6159// RtpParameters).
6160TEST_F(WebRtcVideoChannelTest, DefaultMinAndMaxBitratePropagatedToEncoder) {
6161 FakeVideoSendStream* stream = AddSendStream();
6162 EXPECT_TRUE(channel_->SetSend(true));
6163 EXPECT_TRUE(stream->IsSending());
6164
6165 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6166 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6167 EXPECT_EQ(1u, encoder_config.number_of_streams);
6168 EXPECT_EQ(1u, encoder_config.simulcast_layers.size());
6169 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].min_bitrate_bps);
6170 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].max_bitrate_bps);
6171
6172 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6173 // VideoStreams are created appropriately.
6174 EXPECT_EQ(1u, stream->GetVideoStreams().size());
6175 EXPECT_EQ(cricket::kMinVideoBitrateBps,
6176 stream->GetVideoStreams()[0].min_bitrate_bps);
6177 EXPECT_GT(stream->GetVideoStreams()[0].max_bitrate_bps,
6178 stream->GetVideoStreams()[0].min_bitrate_bps);
6179 EXPECT_EQ(stream->GetVideoStreams()[0].max_bitrate_bps,
6180 stream->GetVideoStreams()[0].target_bitrate_bps);
6181}
6182
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006183// Test that a stream will not be sending if its encoding is made inactive
6184// through SetRtpSendParameters.
Seth Hampson8234ead2018-02-02 15:16:24 -08006185TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersOneEncodingActive) {
deadbeefdbe2b872016-03-22 15:42:00 -07006186 FakeVideoSendStream* stream = AddSendStream();
6187 EXPECT_TRUE(channel_->SetSend(true));
6188 EXPECT_TRUE(stream->IsSending());
6189
6190 // Get current parameters and change "active" to false.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006191 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
deadbeefdbe2b872016-03-22 15:42:00 -07006192 ASSERT_EQ(1u, parameters.encodings.size());
6193 ASSERT_TRUE(parameters.encodings[0].active);
6194 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08006195 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeefdbe2b872016-03-22 15:42:00 -07006196 EXPECT_FALSE(stream->IsSending());
6197
6198 // Now change it back to active and verify we resume sending.
6199 parameters.encodings[0].active = true;
Zach Steinba37b4b2018-01-23 15:02:36 -08006200 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeefdbe2b872016-03-22 15:42:00 -07006201 EXPECT_TRUE(stream->IsSending());
6202}
6203
Seth Hampson8234ead2018-02-02 15:16:24 -08006204// Tests that when active is updated for any simulcast layer then the send
6205// stream's sending state will be updated and it will be reconfigured with the
6206// new appropriate active simulcast streams.
6207TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersMultipleEncodingsActive) {
6208 // Create the stream params with multiple ssrcs for simulcast.
Åsa Persson31cb8f92018-06-27 10:44:56 +02006209 const size_t kNumSimulcastStreams = 3;
Seth Hampson8234ead2018-02-02 15:16:24 -08006210 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
6211 StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
6212 FakeVideoSendStream* fake_video_send_stream = AddSendStream(stream_params);
6213 uint32_t primary_ssrc = stream_params.first_ssrc();
6214
Niels Möller805a27e2019-01-21 12:21:27 +01006215 // Using the FrameForwarder, we manually send a full size
Tommi85959932018-02-07 19:26:06 +01006216 // frame. This allows us to test that ReconfigureEncoder is called
6217 // appropriately.
Niels Möller805a27e2019-01-21 12:21:27 +01006218 webrtc::test::FrameForwarder frame_forwarder;
Seth Hampson8234ead2018-02-02 15:16:24 -08006219 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006220 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
Seth Hampson8234ead2018-02-02 15:16:24 -08006221 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006222 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
6223 1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
6224 rtc::kNumMicrosecsPerSec / 30));
Seth Hampson8234ead2018-02-02 15:16:24 -08006225
6226 // Check that all encodings are initially active.
6227 webrtc::RtpParameters parameters =
6228 channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02006229 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006230 EXPECT_TRUE(parameters.encodings[0].active);
6231 EXPECT_TRUE(parameters.encodings[1].active);
6232 EXPECT_TRUE(parameters.encodings[2].active);
6233 EXPECT_TRUE(fake_video_send_stream->IsSending());
6234
6235 // Only turn on only the middle stream.
6236 parameters.encodings[0].active = false;
6237 parameters.encodings[1].active = true;
6238 parameters.encodings[2].active = false;
6239 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
6240 // Verify that the active fields are set on the VideoChannel.
6241 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02006242 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006243 EXPECT_FALSE(parameters.encodings[0].active);
6244 EXPECT_TRUE(parameters.encodings[1].active);
6245 EXPECT_FALSE(parameters.encodings[2].active);
6246 // Check that the VideoSendStream is updated appropriately. This means its
6247 // send state was updated and it was reconfigured.
6248 EXPECT_TRUE(fake_video_send_stream->IsSending());
6249 std::vector<webrtc::VideoStream> simulcast_streams =
6250 fake_video_send_stream->GetVideoStreams();
Åsa Persson31cb8f92018-06-27 10:44:56 +02006251 EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006252 EXPECT_FALSE(simulcast_streams[0].active);
6253 EXPECT_TRUE(simulcast_streams[1].active);
6254 EXPECT_FALSE(simulcast_streams[2].active);
6255
6256 // Turn off all streams.
6257 parameters.encodings[0].active = false;
6258 parameters.encodings[1].active = false;
6259 parameters.encodings[2].active = false;
6260 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
6261 // Verify that the active fields are set on the VideoChannel.
6262 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02006263 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006264 EXPECT_FALSE(parameters.encodings[0].active);
6265 EXPECT_FALSE(parameters.encodings[1].active);
6266 EXPECT_FALSE(parameters.encodings[2].active);
6267 // Check that the VideoSendStream is off.
6268 EXPECT_FALSE(fake_video_send_stream->IsSending());
6269 simulcast_streams = fake_video_send_stream->GetVideoStreams();
Åsa Persson31cb8f92018-06-27 10:44:56 +02006270 EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006271 EXPECT_FALSE(simulcast_streams[0].active);
6272 EXPECT_FALSE(simulcast_streams[1].active);
6273 EXPECT_FALSE(simulcast_streams[2].active);
6274
Niels Möllerff40b142018-04-09 08:49:14 +02006275 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
Seth Hampson8234ead2018-02-02 15:16:24 -08006276}
6277
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006278// Test that if a stream is reconfigured (due to a codec change or other
6279// change) while its encoding is still inactive, it doesn't start sending.
eladalonf1841382017-06-12 01:16:46 -07006280TEST_F(WebRtcVideoChannelTest,
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006281 InactiveStreamDoesntStartSendingWhenReconfigured) {
6282 // Set an initial codec list, which will be modified later.
6283 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08006284 parameters1.codecs.push_back(GetEngineCodec("VP8"));
6285 parameters1.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006286 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
6287
6288 FakeVideoSendStream* stream = AddSendStream();
6289 EXPECT_TRUE(channel_->SetSend(true));
6290 EXPECT_TRUE(stream->IsSending());
6291
6292 // Get current parameters and change "active" to false.
6293 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6294 ASSERT_EQ(1u, parameters.encodings.size());
6295 ASSERT_TRUE(parameters.encodings[0].active);
6296 parameters.encodings[0].active = false;
6297 EXPECT_EQ(1u, GetFakeSendStreams().size());
6298 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Zach Steinba37b4b2018-01-23 15:02:36 -08006299 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006300 EXPECT_FALSE(stream->IsSending());
6301
6302 // Reorder the codec list, causing the stream to be reconfigured.
6303 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08006304 parameters2.codecs.push_back(GetEngineCodec("VP9"));
6305 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006306 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
6307 auto new_streams = GetFakeSendStreams();
6308 // Assert that a new underlying stream was created due to the codec change.
6309 // Otherwise, this test isn't testing what it set out to test.
6310 EXPECT_EQ(1u, GetFakeSendStreams().size());
6311 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
6312
6313 // Verify that we still are not sending anything, due to the inactive
6314 // encoding.
6315 EXPECT_FALSE(new_streams[0]->IsSending());
6316}
6317
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006318// Test that GetRtpSendParameters returns the currently configured codecs.
eladalonf1841382017-06-12 01:16:46 -07006319TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006320 AddSendStream();
6321 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08006322 parameters.codecs.push_back(GetEngineCodec("VP8"));
6323 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006324 EXPECT_TRUE(channel_->SetSendParameters(parameters));
6325
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006326 webrtc::RtpParameters rtp_parameters =
6327 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006328 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08006329 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
6330 rtp_parameters.codecs[0]);
6331 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
6332 rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006333}
6334
Florent Castellidacec712018-05-24 16:24:21 +02006335// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
6336TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersRtcpCname) {
6337 StreamParams params = StreamParams::CreateLegacy(kSsrc);
6338 params.cname = "rtcpcname";
6339 AddSendStream(params);
6340
6341 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc);
6342 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
6343}
6344
deadbeeffb2aced2017-01-06 23:05:37 -08006345// Test that RtpParameters for send stream has one encoding and it has
6346// the correct SSRC.
eladalonf1841382017-06-12 01:16:46 -07006347TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersSsrc) {
deadbeeffb2aced2017-01-06 23:05:37 -08006348 AddSendStream();
6349
6350 webrtc::RtpParameters rtp_parameters =
6351 channel_->GetRtpSendParameters(last_ssrc_);
6352 ASSERT_EQ(1u, rtp_parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01006353 EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc);
deadbeeffb2aced2017-01-06 23:05:37 -08006354}
6355
Florent Castelliabe301f2018-06-12 18:33:49 +02006356TEST_F(WebRtcVideoChannelTest, DetectRtpSendParameterHeaderExtensionsChange) {
6357 AddSendStream();
6358
6359 webrtc::RtpParameters rtp_parameters =
6360 channel_->GetRtpSendParameters(last_ssrc_);
6361 rtp_parameters.header_extensions.emplace_back();
6362
6363 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
6364
6365 webrtc::RTCError result =
6366 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6367 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
6368}
6369
Florent Castelli87b3c512018-07-18 16:00:28 +02006370TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersDegradationPreference) {
6371 AddSendStream();
6372
Niels Möller805a27e2019-01-21 12:21:27 +01006373 webrtc::test::FrameForwarder frame_forwarder;
6374 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Florent Castelli87b3c512018-07-18 16:00:28 +02006375
6376 webrtc::RtpParameters rtp_parameters =
6377 channel_->GetRtpSendParameters(last_ssrc_);
6378 EXPECT_EQ(rtp_parameters.degradation_preference,
6379 webrtc::DegradationPreference::BALANCED);
6380 rtp_parameters.degradation_preference =
6381 webrtc::DegradationPreference::MAINTAIN_FRAMERATE;
6382
6383 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
6384
6385 webrtc::RtpParameters updated_rtp_parameters =
6386 channel_->GetRtpSendParameters(last_ssrc_);
6387 EXPECT_EQ(updated_rtp_parameters.degradation_preference,
6388 webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
6389
6390 // Remove the source since it will be destroyed before the channel
6391 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6392}
6393
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006394// Test that if we set/get parameters multiple times, we get the same results.
eladalonf1841382017-06-12 01:16:46 -07006395TEST_F(WebRtcVideoChannelTest, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006396 AddSendStream();
6397 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08006398 parameters.codecs.push_back(GetEngineCodec("VP8"));
6399 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006400 EXPECT_TRUE(channel_->SetSendParameters(parameters));
6401
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006402 webrtc::RtpParameters initial_params =
6403 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006404
6405 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08006406 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006407
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006408 // ... And this shouldn't change the params returned by GetRtpSendParameters.
6409 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(last_ssrc_));
6410}
6411
6412// Test that GetRtpReceiveParameters returns the currently configured codecs.
eladalonf1841382017-06-12 01:16:46 -07006413TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersCodecs) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006414 AddRecvStream();
6415 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08006416 parameters.codecs.push_back(GetEngineCodec("VP8"));
6417 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006418 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
6419
6420 webrtc::RtpParameters rtp_parameters =
6421 channel_->GetRtpReceiveParameters(last_ssrc_);
6422 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08006423 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
6424 rtp_parameters.codecs[0]);
6425 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
6426 rtp_parameters.codecs[1]);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006427}
6428
johan073ece42016-08-26 02:59:47 -07006429#if defined(WEBRTC_USE_H264)
eladalonf1841382017-06-12 01:16:46 -07006430TEST_F(WebRtcVideoChannelTest, GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07006431#else
eladalonf1841382017-06-12 01:16:46 -07006432TEST_F(WebRtcVideoChannelTest, DISABLED_GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07006433#endif
johan3859c892016-08-05 09:19:25 -07006434 cricket::VideoRecvParameters parameters;
perkj26752742016-10-24 01:21:16 -07006435 cricket::VideoCodec kH264sprop1(101, "H264");
magjed5dfac562016-11-25 03:56:37 -08006436 kH264sprop1.SetParam(kH264FmtpSpropParameterSets, "uvw");
johan3859c892016-08-05 09:19:25 -07006437 parameters.codecs.push_back(kH264sprop1);
perkj26752742016-10-24 01:21:16 -07006438 cricket::VideoCodec kH264sprop2(102, "H264");
magjed5dfac562016-11-25 03:56:37 -08006439 kH264sprop2.SetParam(kH264FmtpSpropParameterSets, "xyz");
johan3859c892016-08-05 09:19:25 -07006440 parameters.codecs.push_back(kH264sprop2);
6441 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
6442
6443 FakeVideoReceiveStream* recv_stream = AddRecvStream();
6444 const webrtc::VideoReceiveStream::Config& cfg = recv_stream->GetConfig();
6445 webrtc::RtpParameters rtp_parameters =
6446 channel_->GetRtpReceiveParameters(last_ssrc_);
6447 ASSERT_EQ(2u, rtp_parameters.codecs.size());
6448 EXPECT_EQ(kH264sprop1.ToCodecParameters(), rtp_parameters.codecs[0]);
6449 ASSERT_EQ(2u, cfg.decoders.size());
6450 EXPECT_EQ(101, cfg.decoders[0].payload_type);
Niels Möllercb7e1d22018-09-11 15:56:04 +02006451 EXPECT_EQ("H264", cfg.decoders[0].video_format.name);
magjed5dfac562016-11-25 03:56:37 -08006452 const auto it0 =
Niels Möllercb7e1d22018-09-11 15:56:04 +02006453 cfg.decoders[0].video_format.parameters.find(kH264FmtpSpropParameterSets);
6454 ASSERT_TRUE(it0 != cfg.decoders[0].video_format.parameters.end());
magjed5dfac562016-11-25 03:56:37 -08006455 EXPECT_EQ("uvw", it0->second);
johan3859c892016-08-05 09:19:25 -07006456
6457 EXPECT_EQ(102, cfg.decoders[1].payload_type);
Niels Möllercb7e1d22018-09-11 15:56:04 +02006458 EXPECT_EQ("H264", cfg.decoders[1].video_format.name);
magjed5dfac562016-11-25 03:56:37 -08006459 const auto it1 =
Niels Möllercb7e1d22018-09-11 15:56:04 +02006460 cfg.decoders[1].video_format.parameters.find(kH264FmtpSpropParameterSets);
6461 ASSERT_TRUE(it1 != cfg.decoders[1].video_format.parameters.end());
magjed5dfac562016-11-25 03:56:37 -08006462 EXPECT_EQ("xyz", it1->second);
johan3859c892016-08-05 09:19:25 -07006463}
6464
sakal1fd95952016-06-22 00:46:15 -07006465// Test that RtpParameters for receive stream has one encoding and it has
6466// the correct SSRC.
eladalonf1841382017-06-12 01:16:46 -07006467TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersSsrc) {
sakal1fd95952016-06-22 00:46:15 -07006468 AddRecvStream();
6469
6470 webrtc::RtpParameters rtp_parameters =
6471 channel_->GetRtpReceiveParameters(last_ssrc_);
6472 ASSERT_EQ(1u, rtp_parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01006473 EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc);
sakal1fd95952016-06-22 00:46:15 -07006474}
6475
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006476// Test that if we set/get parameters multiple times, we get the same results.
eladalonf1841382017-06-12 01:16:46 -07006477TEST_F(WebRtcVideoChannelTest, SetAndGetRtpReceiveParameters) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006478 AddRecvStream();
6479 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08006480 parameters.codecs.push_back(GetEngineCodec("VP8"));
6481 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006482 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
6483
6484 webrtc::RtpParameters initial_params =
6485 channel_->GetRtpReceiveParameters(last_ssrc_);
6486
6487 // We should be able to set the params we just got.
6488 EXPECT_TRUE(channel_->SetRtpReceiveParameters(last_ssrc_, initial_params));
6489
6490 // ... And this shouldn't change the params returned by
6491 // GetRtpReceiveParameters.
6492 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(last_ssrc_));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006493}
6494
deadbeef3bc15102017-04-20 19:25:07 -07006495// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
6496// aren't signaled. It should always return an empty "RtpEncodingParameters",
6497// even after a packet is received and the unsignaled SSRC is known.
eladalonf1841382017-06-12 01:16:46 -07006498TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersWithUnsignaledSsrc) {
deadbeef3bc15102017-04-20 19:25:07 -07006499 // Call necessary methods to configure receiving a default stream as
6500 // soon as it arrives.
6501 cricket::VideoRecvParameters parameters;
6502 parameters.codecs.push_back(GetEngineCodec("VP8"));
6503 parameters.codecs.push_back(GetEngineCodec("VP9"));
6504 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
6505
6506 // Call GetRtpReceiveParameters before configured to receive an unsignaled
6507 // stream. Should return nothing.
6508 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
6509
6510 // Set a sink for an unsignaled stream.
6511 cricket::FakeVideoRenderer renderer;
6512 // Value of "0" means "unsignaled stream".
6513 EXPECT_TRUE(channel_->SetSink(0, &renderer));
6514
6515 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
6516 // in this method means "unsignaled stream".
6517 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
6518 ASSERT_EQ(1u, rtp_parameters.encodings.size());
6519 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
6520
6521 // Receive VP8 packet.
6522 uint8_t data[kMinRtpPacketLen];
6523 cricket::RtpHeader rtpHeader;
6524 rtpHeader.payload_type = GetEngineCodec("VP8").id;
6525 rtpHeader.seq_num = rtpHeader.timestamp = 0;
6526 rtpHeader.ssrc = kIncomingUnsignalledSsrc;
6527 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
6528 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Niels Möllere6933812018-11-05 13:01:41 +01006529 channel_->OnPacketReceived(&packet, /* packet_time_us */ -1);
deadbeef3bc15102017-04-20 19:25:07 -07006530
6531 // The |ssrc| member should still be unset.
6532 rtp_parameters = channel_->GetRtpReceiveParameters(0);
6533 ASSERT_EQ(1u, rtp_parameters.encodings.size());
6534 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
6535}
6536
eladalonf1841382017-06-12 01:16:46 -07006537void WebRtcVideoChannelTest::TestReceiverLocalSsrcConfiguration(
Peter Boström3548dd22015-05-22 18:48:36 +02006538 bool receiver_first) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02006539 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström3548dd22015-05-22 18:48:36 +02006540
6541 const uint32_t kSenderSsrc = 0xC0FFEE;
Peter Boströmdfa28152015-10-21 17:21:10 +02006542 const uint32_t kSecondSenderSsrc = 0xBADCAFE;
Peter Boström3548dd22015-05-22 18:48:36 +02006543 const uint32_t kReceiverSsrc = 0x4711;
Peter Boströmdfa28152015-10-21 17:21:10 +02006544 const uint32_t kExpectedDefaultReceiverSsrc = 1;
Peter Boström3548dd22015-05-22 18:48:36 +02006545
6546 if (receiver_first) {
6547 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
6548 std::vector<FakeVideoReceiveStream*> receive_streams =
6549 fake_call_->GetVideoReceiveStreams();
6550 ASSERT_EQ(1u, receive_streams.size());
Peter Boströmdfa28152015-10-21 17:21:10 +02006551 // Default local SSRC when we have no sender.
6552 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
6553 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02006554 }
6555 AddSendStream(StreamParams::CreateLegacy(kSenderSsrc));
6556 if (!receiver_first)
6557 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
6558 std::vector<FakeVideoReceiveStream*> receive_streams =
6559 fake_call_->GetVideoReceiveStreams();
6560 ASSERT_EQ(1u, receive_streams.size());
6561 EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boströmdfa28152015-10-21 17:21:10 +02006562
6563 // Removing first sender should fall back to another (in this case the second)
6564 // local send stream's SSRC.
6565 AddSendStream(StreamParams::CreateLegacy(kSecondSenderSsrc));
6566 ASSERT_TRUE(channel_->RemoveSendStream(kSenderSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02006567 receive_streams = fake_call_->GetVideoReceiveStreams();
Peter Boströmdfa28152015-10-21 17:21:10 +02006568 ASSERT_EQ(1u, receive_streams.size());
6569 EXPECT_EQ(kSecondSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
6570
6571 // Removing the last sender should fall back to default local SSRC.
6572 ASSERT_TRUE(channel_->RemoveSendStream(kSecondSenderSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02006573 receive_streams = fake_call_->GetVideoReceiveStreams();
Peter Boströmdfa28152015-10-21 17:21:10 +02006574 ASSERT_EQ(1u, receive_streams.size());
6575 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
6576 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02006577}
6578
eladalonf1841382017-06-12 01:16:46 -07006579TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrc) {
Peter Boström3548dd22015-05-22 18:48:36 +02006580 TestReceiverLocalSsrcConfiguration(false);
6581}
6582
eladalonf1841382017-06-12 01:16:46 -07006583TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrcOnExistingReceivers) {
Peter Boström3548dd22015-05-22 18:48:36 +02006584 TestReceiverLocalSsrcConfiguration(true);
6585}
6586
eladalonf1841382017-06-12 01:16:46 -07006587class WebRtcVideoChannelSimulcastTest : public testing::Test {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006588 public:
eladalonf1841382017-06-12 01:16:46 -07006589 WebRtcVideoChannelSimulcastTest()
Sebastian Jansson8f83b422018-02-21 13:07:13 +01006590 : fake_call_(),
Magnus Jedvert02e7a192017-09-23 17:21:32 +02006591 encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
6592 decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08006593 mock_rate_allocator_factory_(
6594 new webrtc::MockVideoBitrateAllocatorFactory),
Anders Carlsson67537952018-05-03 11:28:29 +02006595 engine_(std::unique_ptr<cricket::FakeWebRtcVideoEncoderFactory>(
Magnus Jedvert02e7a192017-09-23 17:21:32 +02006596 encoder_factory_),
Anders Carlsson67537952018-05-03 11:28:29 +02006597 std::unique_ptr<cricket::FakeWebRtcVideoDecoderFactory>(
Jiawei Ouc2ebe212018-11-08 10:02:56 -08006598 decoder_factory_),
6599 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>(
6600 mock_rate_allocator_factory_)),
magjed2475ae22017-09-12 04:42:15 -07006601 last_ssrc_(0) {}
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006602
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00006603 void SetUp() override {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02006604 encoder_factory_->AddSupportedVideoCodecType("VP8");
Sebastian Jansson84848f22018-11-16 10:40:36 +01006605 channel_.reset(engine_.CreateMediaChannel(&fake_call_, GetMediaConfig(),
6606 VideoOptions(),
6607 webrtc::CryptoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08006608 channel_->OnReadyToSend(true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006609 last_ssrc_ = 123;
6610 }
6611
6612 protected:
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006613 void VerifySimulcastSettings(const VideoCodec& codec,
perkj26752742016-10-24 01:21:16 -07006614 int capture_width,
6615 int capture_height,
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006616 size_t num_configured_streams,
sprang429600d2017-01-26 06:12:26 -08006617 size_t expected_num_streams,
6618 bool screenshare,
6619 bool conference_mode) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02006620 cricket::VideoSendParameters parameters;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02006621 parameters.codecs.push_back(codec);
sprang429600d2017-01-26 06:12:26 -08006622 parameters.conference_mode = conference_mode;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02006623 ASSERT_TRUE(channel_->SetSendParameters(parameters));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006624
Peter Boström0c4e06b2015-10-07 12:23:21 +02006625 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
henrikg91d6ede2015-09-17 00:24:34 -07006626 RTC_DCHECK(num_configured_streams <= ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006627 ssrcs.resize(num_configured_streams);
6628
sprangf24a0642017-02-28 13:23:26 -08006629 AddSendStream(CreateSimStreamParams("cname", ssrcs));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00006630 // Send a full-size frame to trigger a stream reconfiguration to use all
6631 // expected simulcast layers.
Niels Möller805a27e2019-01-21 12:21:27 +01006632 webrtc::test::FrameForwarder frame_forwarder;
6633 cricket::FakeFrameSource frame_source(capture_width, capture_height,
6634 rtc::kNumMicrosecsPerSec / 30);
6635
sprangf24a0642017-02-28 13:23:26 -08006636 VideoOptions options;
6637 if (screenshare)
Oskar Sundbom78807582017-11-16 11:09:55 +01006638 options.is_screencast = screenshare;
Niels Möller805a27e2019-01-21 12:21:27 +01006639 EXPECT_TRUE(
6640 channel_->SetVideoSend(ssrcs.front(), &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08006641 // Fetch the latest stream since SetVideoSend() may recreate it if the
6642 // screen content setting is changed.
6643 FakeVideoSendStream* stream = fake_call_.GetVideoSendStreams().front();
pbos@webrtc.org86196c42015-02-16 21:02:00 +00006644 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006645 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006646
Zach Stein3ca452b2018-01-18 10:01:24 -08006647 auto rtp_parameters = channel_->GetRtpSendParameters(kSsrcs3[0]);
6648 EXPECT_EQ(num_configured_streams, rtp_parameters.encodings.size());
6649
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006650 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6651 ASSERT_EQ(expected_num_streams, video_streams.size());
6652
sprang429600d2017-01-26 06:12:26 -08006653 std::vector<webrtc::VideoStream> expected_streams;
6654 if (conference_mode) {
6655 expected_streams = GetSimulcastConfig(
6656 num_configured_streams, capture_width, capture_height, 0,
Seth Hampson24722b32017-12-22 09:36:42 -08006657 webrtc::kDefaultBitratePriority, kDefaultQpMax,
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +02006658 kDefaultVideoMaxFramerate, screenshare, true);
sprang3ebabf12017-02-16 07:35:22 -08006659 if (screenshare) {
6660 for (const webrtc::VideoStream& stream : expected_streams) {
6661 // Never scale screen content.
Danil Chapovalov350531e2018-06-08 11:04:04 +00006662 EXPECT_EQ(stream.width, rtc::checked_cast<size_t>(capture_width));
6663 EXPECT_EQ(stream.height, rtc::checked_cast<size_t>(capture_height));
sprang3ebabf12017-02-16 07:35:22 -08006664 }
6665 }
sprang429600d2017-01-26 06:12:26 -08006666 } else {
6667 webrtc::VideoStream stream;
6668 stream.width = capture_width;
6669 stream.height = capture_height;
6670 stream.max_framerate = kDefaultVideoMaxFramerate;
Åsa Persson45bbc8a2017-11-13 10:16:47 +01006671 stream.min_bitrate_bps = cricket::kMinVideoBitrateBps;
sprang429600d2017-01-26 06:12:26 -08006672 stream.target_bitrate_bps = stream.max_bitrate_bps =
Åsa Perssonbdee46d2018-06-25 11:28:06 +02006673 GetMaxDefaultBitrateBps(capture_width, capture_height);
sprang429600d2017-01-26 06:12:26 -08006674 stream.max_qp = kDefaultQpMax;
6675 expected_streams.push_back(stream);
6676 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006677
6678 ASSERT_EQ(expected_streams.size(), video_streams.size());
6679
6680 size_t num_streams = video_streams.size();
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00006681 int total_max_bitrate_bps = 0;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006682 for (size_t i = 0; i < num_streams; ++i) {
6683 EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
6684 EXPECT_EQ(expected_streams[i].height, video_streams[i].height);
6685
6686 EXPECT_GT(video_streams[i].max_framerate, 0);
6687 EXPECT_EQ(expected_streams[i].max_framerate,
6688 video_streams[i].max_framerate);
6689
6690 EXPECT_GT(video_streams[i].min_bitrate_bps, 0);
6691 EXPECT_EQ(expected_streams[i].min_bitrate_bps,
6692 video_streams[i].min_bitrate_bps);
6693
6694 EXPECT_GT(video_streams[i].target_bitrate_bps, 0);
6695 EXPECT_EQ(expected_streams[i].target_bitrate_bps,
6696 video_streams[i].target_bitrate_bps);
6697
6698 EXPECT_GT(video_streams[i].max_bitrate_bps, 0);
6699 EXPECT_EQ(expected_streams[i].max_bitrate_bps,
6700 video_streams[i].max_bitrate_bps);
6701
6702 EXPECT_GT(video_streams[i].max_qp, 0);
6703 EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp);
6704
Sergey Silkina796a7e2018-03-01 15:11:29 +01006705 EXPECT_EQ(conference_mode,
6706 expected_streams[i].num_temporal_layers.has_value());
6707
6708 if (conference_mode) {
6709 EXPECT_EQ(expected_streams[i].num_temporal_layers,
6710 video_streams[i].num_temporal_layers);
6711 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00006712
6713 if (i == num_streams - 1) {
6714 total_max_bitrate_bps += video_streams[i].max_bitrate_bps;
6715 } else {
6716 total_max_bitrate_bps += video_streams[i].target_bitrate_bps;
6717 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006718 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00006719
Niels Möllerff40b142018-04-09 08:49:14 +02006720 EXPECT_TRUE(channel_->SetVideoSend(ssrcs.front(), nullptr, nullptr));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006721 }
6722
6723 FakeVideoSendStream* AddSendStream() {
6724 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++));
6725 }
6726
6727 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
Yves Gerey665174f2018-06-19 15:03:05 +02006728 size_t num_streams = fake_call_.GetVideoSendStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006729 EXPECT_TRUE(channel_->AddSendStream(sp));
6730 std::vector<FakeVideoSendStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02006731 fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006732 EXPECT_EQ(num_streams + 1, streams.size());
6733 return streams[streams.size() - 1];
6734 }
6735
6736 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02006737 return fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006738 }
6739
6740 FakeVideoReceiveStream* AddRecvStream() {
6741 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++));
6742 }
6743
6744 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
Yves Gerey665174f2018-06-19 15:03:05 +02006745 size_t num_streams = fake_call_.GetVideoReceiveStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006746 EXPECT_TRUE(channel_->AddRecvStream(sp));
6747 std::vector<FakeVideoReceiveStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02006748 fake_call_.GetVideoReceiveStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006749 EXPECT_EQ(num_streams + 1, streams.size());
6750 return streams[streams.size() - 1];
6751 }
6752
skvlad11a9cbf2016-10-07 11:53:05 -07006753 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +02006754 FakeCall fake_call_;
Magnus Jedvert02e7a192017-09-23 17:21:32 +02006755 cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
6756 cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
Jiawei Ouc2ebe212018-11-08 10:02:56 -08006757 webrtc::MockVideoBitrateAllocatorFactory* mock_rate_allocator_factory_;
eladalonf1841382017-06-12 01:16:46 -07006758 WebRtcVideoEngine engine_;
kwiberg686a8ef2016-02-26 03:00:35 -08006759 std::unique_ptr<VideoMediaChannel> channel_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02006760 uint32_t last_ssrc_;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006761};
6762
eladalonf1841382017-06-12 01:16:46 -07006763TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith2SimulcastStreams) {
sprang429600d2017-01-26 06:12:26 -08006764 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 640, 360, 2, 2, false,
6765 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006766}
6767
eladalonf1841382017-06-12 01:16:46 -07006768TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith3SimulcastStreams) {
sprang429600d2017-01-26 06:12:26 -08006769 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, false,
6770 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006771}
6772
6773// Test that we normalize send codec format size in simulcast.
eladalonf1841382017-06-12 01:16:46 -07006774TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
sprang429600d2017-01-26 06:12:26 -08006775 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 541, 271, 2, 2, false,
6776 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00006777}
sprang429600d2017-01-26 06:12:26 -08006778
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02006779TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForScreenshare) {
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02006780 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
6781 false);
6782}
6783
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02006784TEST_F(WebRtcVideoChannelSimulcastTest,
6785 SetSendCodecsForConferenceModeScreenshare) {
Erik Språng72e52ee2018-11-29 11:41:53 +01006786 webrtc::test::ScopedFieldTrials field_trials(
6787 "WebRTC-SimulcastScreenshare/Disabled/");
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02006788 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
6789 true);
6790}
6791
eladalonf1841382017-06-12 01:16:46 -07006792TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForSimulcastScreenshare) {
sprang429600d2017-01-26 06:12:26 -08006793 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 2, true,
6794 true);
6795}
6796
eladalonf1841382017-06-12 01:16:46 -07006797TEST_F(WebRtcVideoChannelSimulcastTest,
sprangfe627f32017-03-29 08:24:59 -07006798 NoSimulcastScreenshareWithoutConference) {
sprangfe627f32017-03-29 08:24:59 -07006799 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
6800 false);
6801}
6802
Yves Gereyb6a89422018-10-08 10:08:32 +02006803class WebRtcVideoFakeClock {
Jonas Oreland49ac5952018-09-26 16:04:32 +02006804 public:
Yves Gereyb6a89422018-10-08 10:08:32 +02006805 WebRtcVideoFakeClock() {
Jonas Oreland49ac5952018-09-26 16:04:32 +02006806 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1)); // avoid time=0
6807 }
6808 rtc::ScopedFakeClock fake_clock_;
6809};
6810
Yves Gereyb6a89422018-10-08 10:08:32 +02006811// The fake clock needs to be initialized before the call, and not
6812// destroyed until after all threads spawned by the test have been stopped.
6813// This mixin ensures that.
6814class WebRtcVideoChannelTestWithClock : public WebRtcVideoFakeClock,
6815 public WebRtcVideoChannelBaseTest {};
6816
Jonas Oreland49ac5952018-09-26 16:04:32 +02006817TEST_F(WebRtcVideoChannelTestWithClock, GetSources) {
6818 uint8_t data1[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
6819 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
6820
6821 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
6822
6823 rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
6824 rtc::SetBE32(packet1.data() + 8, kSsrc);
6825 channel_->SetSink(kDefaultReceiveSsrc, NULL);
6826 EXPECT_TRUE(SetDefaultCodec());
6827 EXPECT_TRUE(SetSend(true));
6828 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller29e13fd2018-12-17 12:35:30 +01006829 channel_->OnPacketReceived(&packet1, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02006830
6831 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
6832 EXPECT_EQ(1u, sources.size());
6833 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
6834 int64_t timestamp1 = sources[0].timestamp_ms();
6835
6836 // a new packet.
6837 int64_t timeDeltaMs = 1;
6838 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(timeDeltaMs));
Niels Möller29e13fd2018-12-17 12:35:30 +01006839 channel_->OnPacketReceived(&packet1, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02006840 int64_t timestamp2 = channel_->GetSources(kSsrc)[0].timestamp_ms();
6841 EXPECT_EQ(timestamp2, timestamp1 + timeDeltaMs);
6842
6843 // It only keeps 10s of history.
6844 fake_clock_.AdvanceTime(webrtc::TimeDelta::seconds(10));
6845 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1));
6846 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
6847}
6848
6849TEST_F(WebRtcVideoChannelTestWithClock, GetContributingSources) {
6850 uint8_t data1[] = {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6851 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
6852
6853 uint32_t kCsrc = 4321u;
6854 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
6855 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
6856
6857 rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
6858 rtc::SetBE32(packet1.data() + 8, kSsrc);
6859 rtc::SetBE32(packet1.data() + 12, kCsrc);
6860 channel_->SetSink(kDefaultReceiveSsrc, NULL);
6861 EXPECT_TRUE(SetDefaultCodec());
6862 EXPECT_TRUE(SetSend(true));
6863 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller29e13fd2018-12-17 12:35:30 +01006864 channel_->OnPacketReceived(&packet1, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02006865
6866 {
6867 ASSERT_EQ(2u, channel_->GetSources(kSsrc).size());
6868 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
6869 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
6870 EXPECT_EQ(sources[0].timestamp_ms(), sources[1].timestamp_ms());
6871 // 1 SSRC and 1 CSRC.
6872 EXPECT_EQ(1, std::count_if(sources.begin(), sources.end(),
6873 [](const webrtc::RtpSource& source) {
6874 return source.source_type() ==
6875 webrtc::RtpSourceType::SSRC;
6876 }));
6877 EXPECT_EQ(1, std::count_if(sources.begin(), sources.end(),
6878 [](const webrtc::RtpSource& source) {
6879 return source.source_type() ==
6880 webrtc::RtpSourceType::CSRC;
6881 }));
6882 }
6883 int64_t timestamp1 = channel_->GetSources(kSsrc)[0].timestamp_ms();
6884
6885 // a new packet with only ssrc (i.e no csrc).
6886 uint8_t data2[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
6887 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
6888 rtc::CopyOnWriteBuffer packet2(data2, sizeof(data2));
6889 rtc::SetBE32(packet2.data() + 8, kSsrc);
6890
6891 int64_t timeDeltaMs = 1;
6892 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(timeDeltaMs));
Niels Möller29e13fd2018-12-17 12:35:30 +01006893 channel_->OnPacketReceived(&packet2, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02006894
6895 {
6896 ASSERT_EQ(2u, channel_->GetSources(kSsrc).size());
6897 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
6898 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
6899 EXPECT_NE(sources[0].timestamp_ms(), sources[1].timestamp_ms());
6900 // 1 SSRC and 1 CSRC.
6901 EXPECT_EQ(1, std::count_if(sources.begin(), sources.end(),
6902 [](const webrtc::RtpSource& source) {
6903 return source.source_type() ==
6904 webrtc::RtpSourceType::SSRC;
6905 }));
6906 EXPECT_EQ(1, std::count_if(sources.begin(), sources.end(),
6907 [](const webrtc::RtpSource& source) {
6908 return source.source_type() ==
6909 webrtc::RtpSourceType::CSRC;
6910 }));
6911 auto ssrcSource = std::find_if(
6912 sources.begin(), sources.end(), [](const webrtc::RtpSource& source) {
6913 return source.source_type() == webrtc::RtpSourceType::SSRC;
6914 });
6915 auto csrcSource = std::find_if(
6916 sources.begin(), sources.end(), [](const webrtc::RtpSource& source) {
6917 return source.source_type() == webrtc::RtpSourceType::CSRC;
6918 });
6919
6920 EXPECT_EQ(ssrcSource->timestamp_ms(), timestamp1 + timeDeltaMs);
6921 EXPECT_EQ(csrcSource->timestamp_ms(), timestamp1);
6922 }
6923
6924 // It only keeps 10s of history.
6925 fake_clock_.AdvanceTime(webrtc::TimeDelta::seconds(10));
6926
6927 {
6928 ASSERT_EQ(1u, channel_->GetSources(kSsrc).size());
6929 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
6930 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
6931 EXPECT_EQ(1, std::count_if(sources.begin(), sources.end(),
6932 [](const webrtc::RtpSource& source) {
6933 return source.source_type() ==
6934 webrtc::RtpSourceType::SSRC;
6935 }));
6936 EXPECT_EQ(0, std::count_if(sources.begin(), sources.end(),
6937 [](const webrtc::RtpSource& source) {
6938 return source.source_type() ==
6939 webrtc::RtpSourceType::CSRC;
6940 }));
6941 }
6942
6943 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1));
6944 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
6945 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
6946}
6947
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00006948} // namespace cricket